Generic.xaml中的UI代码:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCustomControlLibrary1">
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="PART_ContentTextBox" Text="{TemplateBinding ContentMsg}"/>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button Margin="10"
Grid.Column="0" Grid.Row="0" Content="1" x:Name="PART_Button"/>
<Button Command="local:CustomControl1.TestCommand" CommandParameter="1" Margin="10" Grid.Column="0" Grid.Row="1" Content="2" x:Name="PART_Button2"/>
<Button Command="local:CustomControl1.TestCommand" CommandParameter="2" Margin="10" Grid.Column="0" Grid.Row="2" Content="3" x:Name="PART_Button3"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Margin="10" Grid.Column="1" Grid.Row="0" Content="4" x:Name="PART_Button4"/>
<Button Margin="10" Grid.Column="1" Grid.Row="1" Content="5" x:Name="PART_Button5"/>
<Button Margin="10" Grid.Column="1" Grid.Row="2" Content="6" x:Name="PART_Button6"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Margin="10" Grid.Column="2" Grid.Row="0" Content="7" x:Name="PART_Button7"/>
<Button Margin="10" Grid.Column="2" Grid.Row="1" Content="8" x:Name="PART_Button8"/>
<Button Margin="10" Grid.Column="2" Grid.Row="2" Content="9" x:Name="PART_Button9"/>
</StackPanel>
</StackPanel>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
后台代码中, 对Command进行声明和初始化以及寻找元素名, 然后在后台寻找此元素进行相应的操作
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfCustomControlLibrary1
{
[TemplatePart(Name = CustomControl1.ElementContentTextBox, Type = typeof(TextBlock))]
public class CustomControl1 : Control
{
public CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
ContentMsg = "Hello World";
}
private const string ElementContentTextBox = "PART_ContentTextBox";
private const string Elementbutton = "PART_Button";
Button button = null;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
button = GetTemplateChild(Elementbutton) as Button;
button.Click += Button_Click;
CommandManager.RegisterClassCommandBinding(typeof(CustomControl1), new CommandBinding(TestCommand, TestExecute, TestCanExecute));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ContentMsg = "李四";
}
/// <summary>
/// Registers a dependency property as backing store for the Content property
/// </summary>
public static readonly DependencyProperty ContentMsgProperty =
DependencyProperty.Register("ContentMsg", typeof(object), typeof(CustomControl1),
new FrameworkPropertyMetadata(null ));
/// <summary>
/// Gets or sets the Content.
/// </summary>
/// <value>The Content.</value>
public object ContentMsg
{
get { return (object)GetValue(ContentMsgProperty); }
set { SetValue(ContentMsgProperty, value); }
}
/// <summary>
/// ICommand 属性
/// </summary>
public ICommand ContextMenuCommand
{
get { return (ICommand)GetValue(ContextMenuCommandProperty); }
set { SetValue(ContextMenuCommandProperty, value); }
}
/// <summary>
/// ICommand DependencyProperty
/// </summary>
public static readonly DependencyProperty ContextMenuCommandProperty =
DependencyProperty.Register("ContextMenuCommand", typeof(ICommand), typeof(CustomControl1),
new PropertyMetadata(null));
public static readonly RoutedUICommand TestCommand =new RoutedUICommand("Test", "TestCommand", typeof(CustomControl1));
private static void TestCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void TestExecute(object sender, ExecutedRoutedEventArgs e)
{
CustomControl1 c = sender as CustomControl1;
if (c == null) return;
//你的计算逻辑
ContentMsg = e.Parameter;
}
}
}
对于上面TemplatePartAttribute和Command.两种的使用方法分别是
1、 TemplatePartAttribute就是对UI中的元素命名, 然后在后台寻找此元素进行相应的操作(元素命名以”PART_“开始).此方法不建议使用,因为UI与逻辑耦合
2、建议使用Command,因为它能使UI和逻辑分离. 外部改写UI后, 只需对相应的元素重新绑定内置的Command就可以正常地工作
3、在项目中使用时
<Window x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
xmlns:custom="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<custom:CustomControl1 ContentMsg="{Binding DateTimeMsg,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
x:Name="mycustom" HorizontalAlignment="Left" Margin="55,30,0,0" VerticalAlignment="Top"></custom:CustomControl1>
<Button Content="dsafsdf" Click="Button_Click" Height="40" Width="100" Margin="10"></Button>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfCustomControlLibrary1;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainViewModel mainViewModel = new MainViewModel();
public MainWindow()
{
InitializeComponent();
mainViewModel.DateTimeMsg = "张三";
this.DataContext = mainViewModel;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(mainViewModel.DateTimeMsg.ToString());
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfCustomControlLibrary1
{
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _DateTimeMsg;
public string DateTimeMsg
{
get
{
return _DateTimeMsg;
}
set
{
_DateTimeMsg = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("DateTimeMsg"));
}
}
}
private string _ContentMsg;
public string ContentMsg
{
get
{
return _ContentMsg;
}
set
{
_ContentMsg = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("ContentMsg"));
}
}
}
}
}
![](https://img-blog.csdnimg.cn/0884f8d0476049f283ad5f8b58c12778.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiR5Y-v5Lul5pWZ5L2gQysr5LmI,size_7,color_FFFFFF,t_70,g_se,x_16)