我可以将这块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"
资源是一个通用的标识符,您可以根据需要调用它,然后您可以像这样引用您的控件: