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

相关推荐
△曉風殘月〆19 小时前
WPF中的布局
wpf
阿飞_95271 天前
WPF 自定义用户控件(Content根据加减按钮改变值)
wpf
△曉風殘月〆1 天前
如何在Visual Studio 2019中创建.Net Core WPF工程
wpf
王五周八1 天前
kafka的成神秘籍(java)
java·kafka·wpf
你的头发呢.2 天前
wpf实现新用户页面引导
开发语言·wpf
Slow菜鸟2 天前
SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz
spring boot·分布式·wpf
落落落sss2 天前
微服务概述
java·数据库·sql·微服务·架构·wpf·状态模式
weixin_464078073 天前
wpf加载带材料的3D模型(下载的3D预览一样有纹理)
c#·wpf
暮雪倾风3 天前
【WPF开发】如何设置窗口背景颜色以及背景图片
ui·wpf