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

相关推荐
执笔论英雄15 小时前
【大模型推理】VLLM 引擎使用
wpf·vllm
LateFrames15 小时前
动画性能比对:WPF / WinUI3 / WebView2
wpf·webview·用户体验·winui3
阿湯哥2 天前
多智能体架构深度解析:企业落地如何选择Skills与SubAgents?
架构·wpf
源之缘-OFD先行者2 天前
自研 WPF 鸟情图表:性能与灵活的双重突破
wpf
Moqiqiuzi2 天前
WPF单实例启动
wpf
Moqiqiuzi2 天前
WPF程序打包成安装包的方法
wpf
码农水水2 天前
国家电网Java面试被问:TCP的BBR拥塞控制算法原理
java·开发语言·网络·分布式·面试·wpf
码农水水2 天前
京东Java面试被问:HTTP/2的多路复用和头部压缩实现
java·开发语言·分布式·http·面试·php·wpf
闻缺陷则喜何志丹3 天前
【C# WPF】TextBox的数据绑定
ui·c#·wpf·mvvm·数据绑定·textbox
码农水水4 天前
得物Java面试被问:大规模数据的分布式排序和聚合
java·开发语言·spring boot·分布式·面试·php·wpf