我可以将这块XAML变成可重复使用的“控件”吗?

我有一个Grid ,在那个网格中,我有这个:

                             

StackPanel实际上意味着保存许多GridButtonItem项。 有没有办法,我可以以某种方式制作GridButtonItem的“模板”,然后为每个我想添加到StackPanel ,只需设置图像和文本属性?

像这样的东西(只是用于演示的伪代码):

                  

因此,添加的每一个都会获取行/列定义,以及嵌入的Image和两个TextBlock。 然后我只为每一个添加了三个属性。

这可能吗?

您可以使用UserControl (两种不同的方式)或DataTemplate来完成此操作。 让我们一起使用DataTemplate ,因为stuicidle已经巧妙地演示了一种UserControl方法。

使用DataTemplate还有几种不同的方法可以做到这一点。

我们将做一些名为隐式 DataTemplate的事情。 它是在Resources创建的,但它没有x:Key属性,只有DataType="{x:Type local:GridItemViewModel}"属性。 这将是这样的:无论DataTemplate在何处,只要XAML需要显示GridItemViewModel并且没有指定要显示它的模板,它就会使用该隐式模板。

清楚如泥! 欢迎来到XAML学习曲线。

ViewModels.cs

 using System; using System.ComponentModel; using System.Windows.Media; namespace GridItemAnswer { #region ViewModelBase Class public class ViewModelBase : INotifyPropertyChanged { #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); #endregion INotifyPropertyChanged } #endregion ViewModelBase Class #region GridItemViewModel Class public class GridItemViewModel : ViewModelBase { #region LabelText Property private String _labelText = null; public String LabelText { get { return _labelText; } set { if (value != _labelText) { _labelText = value; OnPropertyChanged(); } } } #endregion LabelText Property #region Path Property private String _path = null; public String Path { get { return _path; } set { if (value != _path) { _path = value; OnPropertyChanged(); } } } #endregion Path Property #region ImageSource Property private ImageSource _imageSource = null; public ImageSource ImageSource { get { return _imageSource; } set { if (value != _imageSource) { _imageSource = value; OnPropertyChanged(); } } } #endregion ImageSource Property } #endregion GridItemViewModel Class } 

MainWindow.xaml

                                  

您可以将网格控件放入UserControl,然后在整个项目中重用UserControl。 我有一个简单的例子,用标签和文本框来做这件事。

这是XAML:

       

您希望能够设置的任何属性(例如图像文本等)必须绑定到后面代码中的依赖项属性。 代码背后:

  public partial class LabelAndTextbox : UserControl { ///  /// Gets or sets the Label which is displayed next to the field ///  public String Label { get { return (String)GetValue(LabelContent); } set { SetValue(LabelContent, value); } } ///  /// Identified the Label dependency property ///  public static readonly DependencyProperty LabelContent = DependencyProperty.Register("Label", typeof(string), typeof(LabelAndTextbox), new PropertyMetadata("")); public object Text { get { return (object)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(object), typeof(LabelAndTextbox), new PropertyMetadata(null)); public Double LabelWidth { get { return (Double)GetValue(LabelWidthProperty); } set { SetValue(LabelWidthProperty, value); } } public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register("LabelWidth", typeof(Double), typeof(LabelAndTextbox), new PropertyMetadata()); public Double TextboxWidth { get { return (Double)GetValue(TextboxWidthProperty); } set { SetValue(TextboxWidthProperty, value); } } public static readonly DependencyProperty TextboxWidthProperty = DependencyProperty.Register("TextboxWidth", typeof(Double), typeof(LabelAndTextbox), new PropertyMetadata()); public bool TextboxReadOnly { get { return (bool)GetValue(TextboxReadOnlyProperty); } set { SetValue(TextboxReadOnlyProperty, value); } } public static readonly DependencyProperty TextboxReadOnlyProperty = DependencyProperty.Register("TextboxReadOnly", typeof(bool), typeof(LabelAndTextbox), new FrameworkPropertyMetadata()); public HorizontalAlignment TextboxHorizontalContentAlgnment { get { return (HorizontalAlignment)GetValue(TextboxHorizontalContentAlgnmentProperty); } set { SetValue(TextboxHorizontalContentAlgnmentProperty, value); } } public static readonly DependencyProperty TextboxHorizontalContentAlgnmentProperty = DependencyProperty.Register("TextboxHorizontalContentAlgnment", typeof(HorizontalAlignment), typeof(LabelAndTextbox), new FrameworkPropertyMetadata()); public LabelAndTextbox() { InitializeComponent(); } } 

然后,您需要将XAML文件中的引用添加到UserControl,如下所示:

 xmlns:Resource="clr-namespace:ProjectNamespace.FolderContainingYourControl" 

资源是一个通用的标识符,您可以根据需要调用它,然后您可以像这样引用您的控件: