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());
}
}
}
运行效果: