WPF DataBinding 不工作 - 使用代码创建 DataTemplate
WPF DataBinding Not working - creation of DataTemplate using code
我在 xaml 代码中创建了一个名为 ValueTreeView 的树视图,它使用在以下代码中创建的数据模板,它完全绑定到通用 class ValueHolder
这是用于绑定的class
public class ValueHolder
{
public string VHName{ get; set; }
public string VHValue{ get; set; }
}
这是具有树视图的用户控件
public partial class UserControl1 : UserControl
{
ObservableCollection<ValueHolder> source;
public UserControl1()
{
InitializeComponent();
source= new ObservableCollection<ValueHolder>();
//Data Template for the treeView
DataTemplate cardLayout = new DataTemplate();
cardLayout.DataType = typeof(ValueHolder);
FrameworkElementFactory ValueStack= new FrameworkElementFactory(typeof(StackPanel));
ValueStack.Name = "Details";
ValueStack.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
FrameworkElementFactory VName= new FrameworkElementFactory(typeof(TextBlock));
VName.SetBinding(TextBlock.TextProperty, new Binding("VHName"));
ValueStack.AppendChild(VName);
FrameworkElementFactory Space = new FrameworkElementFactory(typeof(TextBlock));
Space.SetValue(TextBlock.WidthProperty, 10.0);
ValueStack.AppendChild(Space);
FrameworkElementFactory VValue= new FrameworkElementFactory(typeof(TextBlock));
VValue.SetBinding(TextBlock.TextProperty, new Binding("VHValue"));
ValueStack.AppendChild(VValue);
cardLayout.VisualTree = ValueStack;
ValueTreeView.ItemTemplate = cardLayout;
//Initializing the TreeViewItems
ValueHolder vh1 = new ValueHolder() { VHName = "VH1", VHValue = "456"};
ValueHolder vh2 = new ValueHolder() { VHName = "VH2", VHValue = "578"};
ValueHolder vh3 = new ValueHolder() { VHName = "VH3", VHValue = "235"};
source.Add(vh1);
source.Add(vh2);
source.Add(vh3);
ValueTreeView.ItemsSource = source;
}
下面是选择项改变时调用的事件处理程序
private void ValueTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var s=((ValueHolder)((TreeView)sender).SelectedItem);
if(s.VHName=="VH2")
s.VHValue = "111";
}
}
每个 TreeViewItem 中的两个文本块绑定到两个 class 变量。
我的问题是当我更改 Class 属性的值时,它没有反映在 UI 中,即使我使用 ObservableCollection 作为 TreeView 的项目源。
事件处理程序更改了 class 的 VHValue 属性,它正在后端更改,但未反映在 UI 中
我的xaml代码:
<UserControl x:Class="Checker.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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TreeView x:Name="ValueTreeView" SelectedItemChanged="ValueTreeView_SelectedItemChanged">
</TreeView>
</Grid>
</UserControl>
ObservableCollection
仅适用于集合更改,不适用于集合中项目的更改。您需要为 ValueHolder
class 实现 INotifyPropertyChanged
接口
更多详情 here
public class ValueHolder : INotifyPropertyChanged
{
private string _VHName;
private string _VHValue;
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;
public string VHName
{
get { return _VHName; }
set
{
_VHName = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("VHName");
}
}
public string VHValue
{
get { return _VHValue; }
set
{
_VHValue= value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("VHValue");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
我在 xaml 代码中创建了一个名为 ValueTreeView 的树视图,它使用在以下代码中创建的数据模板,它完全绑定到通用 class ValueHolder
这是用于绑定的class
public class ValueHolder
{
public string VHName{ get; set; }
public string VHValue{ get; set; }
}
这是具有树视图的用户控件
public partial class UserControl1 : UserControl
{
ObservableCollection<ValueHolder> source;
public UserControl1()
{
InitializeComponent();
source= new ObservableCollection<ValueHolder>();
//Data Template for the treeView
DataTemplate cardLayout = new DataTemplate();
cardLayout.DataType = typeof(ValueHolder);
FrameworkElementFactory ValueStack= new FrameworkElementFactory(typeof(StackPanel));
ValueStack.Name = "Details";
ValueStack.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
FrameworkElementFactory VName= new FrameworkElementFactory(typeof(TextBlock));
VName.SetBinding(TextBlock.TextProperty, new Binding("VHName"));
ValueStack.AppendChild(VName);
FrameworkElementFactory Space = new FrameworkElementFactory(typeof(TextBlock));
Space.SetValue(TextBlock.WidthProperty, 10.0);
ValueStack.AppendChild(Space);
FrameworkElementFactory VValue= new FrameworkElementFactory(typeof(TextBlock));
VValue.SetBinding(TextBlock.TextProperty, new Binding("VHValue"));
ValueStack.AppendChild(VValue);
cardLayout.VisualTree = ValueStack;
ValueTreeView.ItemTemplate = cardLayout;
//Initializing the TreeViewItems
ValueHolder vh1 = new ValueHolder() { VHName = "VH1", VHValue = "456"};
ValueHolder vh2 = new ValueHolder() { VHName = "VH2", VHValue = "578"};
ValueHolder vh3 = new ValueHolder() { VHName = "VH3", VHValue = "235"};
source.Add(vh1);
source.Add(vh2);
source.Add(vh3);
ValueTreeView.ItemsSource = source;
}
下面是选择项改变时调用的事件处理程序
private void ValueTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var s=((ValueHolder)((TreeView)sender).SelectedItem);
if(s.VHName=="VH2")
s.VHValue = "111";
}
}
每个 TreeViewItem 中的两个文本块绑定到两个 class 变量。
我的问题是当我更改 Class 属性的值时,它没有反映在 UI 中,即使我使用 ObservableCollection 作为 TreeView 的项目源。
事件处理程序更改了 class 的 VHValue 属性,它正在后端更改,但未反映在 UI 中
我的xaml代码:
<UserControl x:Class="Checker.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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TreeView x:Name="ValueTreeView" SelectedItemChanged="ValueTreeView_SelectedItemChanged">
</TreeView>
</Grid>
</UserControl>
ObservableCollection
仅适用于集合更改,不适用于集合中项目的更改。您需要为 ValueHolder
class 实现 INotifyPropertyChanged
接口
更多详情 here
public class ValueHolder : INotifyPropertyChanged
{
private string _VHName;
private string _VHValue;
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;
public string VHName
{
get { return _VHName; }
set
{
_VHName = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("VHName");
}
}
public string VHValue
{
get { return _VHValue; }
set
{
_VHValue= value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("VHValue");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}