WPF用户控件的使用

WPF用户控件的使用

先看一下程序结构:

WPF_Test是我的主程序;WPF_LIB是我添加的一个用户控件库,其中UserControl1是一个用户控件;

用户控件xaml代码:

csharp 复制代码
<UserControl x:Class="WPF_LIB.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPF_LIB"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <StackPanel>
            <TextBox Width="100" Height="25" Margin="10" Text="{Binding MyValue,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:UserControl1},UpdateSourceTrigger=PropertyChanged}"/>
            <Button Width="100" Height="25" Margin="10" Content="点击" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=MyCommand}" CommandParameter="{Binding MyCommandParameter,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:UserControl1},UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>
    </Grid>
</UserControl>

效果如下:

后台代码:

其中定义了一个依赖属性和一个命令;

csharp 复制代码
namespace WPF_LIB
{
    /// <summary>
    /// UserControl1.xaml 的交互逻辑
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }


        public string MyValue
        {
            get { return (string)GetValue(MyValueProperty); }
            set { SetValue(MyValueProperty, value); }
        }

        public static readonly DependencyProperty MyValueProperty =
            DependencyProperty.Register("MyValue", typeof(string), typeof(UserControl1), new PropertyMetadata("6666"));


        public object MyCommandParameter
        {
            get { return (object)GetValue(MyCommandParameterProperty); }
            set { SetValue(MyCommandParameterProperty, value); }
        }

        public static readonly DependencyProperty MyCommandParameterProperty =
            DependencyProperty.Register("MyCommandParameter", typeof(object), typeof(UserControl1), new FrameworkPropertyMetadata((object)null));

        public IInputElement MyCommandTarget
        {
            get { return (IInputElement)GetValue(MyCommandTargetProperty); }
            set { SetValue(MyCommandTargetProperty, value); }
        }

        public static readonly DependencyProperty MyCommandTargetProperty =
            DependencyProperty.Register("MyCommandTarget", typeof(IInputElement), typeof(UserControl1), new FrameworkPropertyMetadata((object)null));

        public ICommand MyCommand
        {
            get { return (ICommand)GetValue(MyCommandProperty); }
            set { SetValue(MyCommandProperty, value); }
        }

        public static readonly DependencyProperty MyCommandProperty =
        DependencyProperty.Register("MyCommand", typeof(ICommand), typeof(UserControl1), new PropertyMetadata((ICommand)null, new PropertyChangedCallback(OnCommandChanged)));


        private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UserControl1 userControl1 = d as UserControl1;
            if(userControl1 != null)
            {
                ICommand oldCommand = e.OldValue as ICommand;
                ICommand newCommand = e.NewValue as ICommand;
                userControl1.UpdateCommand(oldCommand,newCommand);
            }
            //ButtonBase buttonBase = (ButtonBase)d;
            //buttonBase.OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue);
        }

        private void UpdateCommand(ICommand oldCommand, ICommand newCommand)
        {
            if (oldCommand != null)
            {
                oldCommand.CanExecuteChanged -= CanExecuteChanged;
                //UnhookCommand(oldCommand);
            }

            if (newCommand != null)
            {
                newCommand.CanExecuteChanged += CanExecuteChanged;
                //HookCommand(newCommand);
            }
        }

        private void CanExecuteChanged(object sender,EventArgs e)
        {
            RoutedCommand command = MyCommand as RoutedCommand;
            if (command != null)
            {
                this.IsEnabled = command.CanExecute(MyCommandParameter, MyCommandTarget);
            }
            else if(MyCommand != null)
            {
                this.IsEnabled = MyCommand.CanExecute(MyCommandParameter);
            }
        }

    }
}

主程序WPF_Test中有一个CommandBase类:

csharp 复制代码
public class CommandBase : ICommand
 {
     public event EventHandler CanExecuteChanged;

     public bool CanExecute(object parameter)
     {
         return DoCanExecute?.Invoke(parameter) == true;
     }

     public void Execute(object parameter)
     {
         DoExecute?.Invoke(parameter);
     }

     public Action<object> DoExecute { get; set; }

     public Func<object, bool> DoCanExecute { get; set; }
 }

主程序xaml代码:

csharp 复制代码
<Window x:Class="WPF_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:control="clr-namespace:WPF_LIB;assembly=WPF_LIB"
        xmlns:local="clr-namespace:WPF_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <control:UserControl1 MyCommand="{Binding TestCommand}" MyCommandParameter="Good!!!" MyValue="Hello!"/>
        </StackPanel>
    </Grid>
</Window>

主程序后台代码:

csharp 复制代码
namespace WPF_Test
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            this.TestCommand = new CommandBase();
            this.TestCommand.DoExecute = new Action<object>(TestFunction);
            this.TestCommand.DoCanExecute = new Func<object, bool>((o) => true);

            this.DataContext = this;

        }

        public CommandBase TestCommand { get; set; }
        private void TestFunction(object obj)
        {
            MessageBox.Show(obj.ToString());
        }
    }

}

运行效果:

参考文件:
https://www.cnblogs.com/weskynet/p/16290422.html

相关推荐
月落.35 分钟前
WPF Prism中的区域(Region)管理
wpf·prism
林子漾19 小时前
【paper】分布式无人水下航行器围捕智能目标
分布式·wpf
wyh要好好学习1 天前
C# WPF 记录DataGrid的表头顺序,下次打开界面时应用到表格中
开发语言·c#·wpf
lgcgkCQ2 天前
任务调度中心-XXL-JOB使用详解
java·wpf·定时任务·任务调度
Vicky&James2 天前
英雄联盟客户端项目:从跨平台Uno Platform到Win UI3的转换只需要30分钟
github·wpf·跨平台·英雄联盟·winui·unoplatform
就是有点傻2 天前
WPF中如何使用区域导航
wpf
她说彩礼65万2 天前
WPF程序设置单例启动(互斥体)
wpf
就是有点傻2 天前
WPF中Prism框架中 IContainerExtension 和 IRegionManager的作用
wpf
月落.2 天前
WPF中MVVM工具包 CommunityToolkit.Mvvm
wpf·mvvm
月落.2 天前
WPF Prism框架
wpf·prism