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

相关推荐
国服第二切图仔18 小时前
HarmonyOS APP《画伴梦工厂》开发第60篇-分布式软总线2.0——多设备协同新范式
分布式·wpf·harmonyos
精神底层1 天前
拒绝 UI 卡死!我用 CSnakes 实时拦截 Python 训练流,在 WPF 中重构了 ScottPlot 5 高性能 AI 看板
python·ui·wpf
爱吃大芒果1 天前
不用多设备模拟器跑通 ShareKit 碰一碰分享
华为·wpf·harmonyos
贪玩的小松鼠2 天前
WPF基础到企业应用系列7——深入剖析依赖属性(WPF/Silverlight核
wpf
界面开发小八哥2 天前
界面控件DevExpress WPF v26.1新版亮点 - TreeView、Spreadsheet控件功能升级
.net·wpf·界面控件·devexpress·ui开发
斯文的八宝粥3 天前
WPF企业内训全程实录(下)
大数据·hadoop·wpf
精明的身影5 天前
深入WPF -- Dispatcher(补)
wpf
云中飞鸿6 天前
该如何进行WPF界面设计
wpf
云中飞鸿7 天前
WPF分哪几块
wpf
newbe365247 天前
我们如何使用 impeccable 优化前端界面设计与实现稳定性
前端·人工智能·分布式·github·aigc·wpf