用户控件依赖项列表视图中的属性绑定
本文关键字:属性 绑定 视图 列表 控件 依赖 用户 | 更新日期: 2023-09-27 18:33:07
当我尝试在列表视图中使用自定义用户控件时,它失败并且仅显示空块(以下文本块有效)。虽然列表视图之外的自定义控件运行良好。怎么了?
MainWindow.xaml
<Grid>
<StackPanel>
<controls:CustomControl x:Name="customControl" CustomText="Test"/>
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<controls:CustomControl CustomObject="{Binding}"/>
<TextBlock Text="{Binding Text}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Grid>
主窗口.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeMyComponent();
}
public System.Collections.ObjectModel.ObservableCollection<CustomClass> CustomCollection { get; set; }
private void InitializeMyComponent()
{
this.CustomCollection = new System.Collections.ObjectModel.ObservableCollection<CustomClass>();
this.CustomCollection.Add(new CustomClass() { Number = 1, Text = "a" });
this.CustomCollection.Add(new CustomClass() { Number = 2, Text = "b" });
this.CustomCollection.Add(new CustomClass() { Number = 3, Text = "c" });
this.listView.ItemsSource = this.CustomCollection;
this.customControl.Custom = new CustomClass() { Number = 0, Text = "customControl" };
}
}
CustomControl.xaml
<Grid>
<StackPanel>
<TextBlock>
<Run x:Name="numberRun" Text="{Binding CustomObject.Number}"/>
<Run x:Name="textRun" Text="{Binding CustomObject.Text}"/>
<Run Text="{Binding CustomText}"/>
</TextBlock>
</StackPanel>
</Grid>
自定义控制.cs
public partial class CustomControl : UserControl
{
public static readonly DependencyProperty CustomObjectProperty;
public static readonly DependencyProperty CustomTextProperty;
static CustomControl()
{
CustomObjectProperty = DependencyProperty.Register("CustomObject", typeof(CustomClass), typeof(CustomControl), new PropertyMetadata(default(CustomClass), OnCustomObjectPropertyChanged));
CustomTextProperty = DependencyProperty.Register("CustomText", typeof(string), typeof(CustomControl), new PropertyMetadata(string.Empty, OnCustomTextPropertyChanged));
}
public CustomControl()
{
InitializeComponent();
this.DataContext = this;
}
public CustomClass CustomObject
{
get
{
return (CustomClass)(this.GetValue(CustomObjectProperty));
}
set
{
this.SetValue(CustomObjectProperty, value);
}
}
public string CustomText
{
get
{
return (string)(this.GetValue(CustomTextProperty));
}
set
{
this.SetValue(CustomTextProperty, value);
}
}
private static void OnCustomObjectPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { }
private static void OnCustomTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { }
}
自定义类.cs
public class CustomClass : INotifyPropertyChanged
{
private int number;
private string text;
public CustomClass()
{
this.number = new int();
this.text = string.Empty;
}
public int Number
{
get
{
return this.number;
}
set
{
this.number = value;
this.OnPropertyChanged();
}
}
public string Text
{
get
{
return this.text;
}
set
{
this.text = value;
this.OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = null)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
设置用户控件对用户控件实例的DataContext
,如下所示
this.DataContext = this;
有效防止绑定到"外部"、继承的数据上下文,如预期的那样
<controls:CustomControl CustomObject="{Binding}"/>
作为一般规则,切勿显式设置用户控件的数据上下文。从用户控件的构造函数中删除上述行,并使用 RelativeSource 在用户控件的 XAML 中编写绑定:
<Run x:Name="numberRun" Text="{Binding CustomObject.Number,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>