[英]WPF TreeView Binding not updating the View
INotifyPropertyChanged 已實現,DataContext 已設置。
這是我的 TreeView:
<TreeView ItemContainerStyle="{StaticResource MaterialDesignTreeViewItemExtended}" x:Name="TestCasesTree" MinWidth="220" ItemsSource="{Binding TestCases.Children, Mode=TwoWay}">
<i:Interaction.Behaviors>
<behaviours:BindableSelectedItemBehavior SelectedItem="{Binding SelectedTreeViewItem, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.Resources>
<con:TestAssessmentToImagePathConverter x:Key="TestAssessmentConverter" />
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=TwoWay}" DataType="{x:Type data:TestCaseNode}">
<StackPanel Margin="0" Orientation="Horizontal">
<Image Source="{Binding TestAssessment, Converter={StaticResource TestAssessmentConverter}}" RenderOptions.BitmapScalingMode="HighQuality" Width="20" Height="20"/>
<TextBlock Margin="8 2 0 0" Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
捆綁:
ItemsSource="{Binding TestCases.Children, Mode=TwoWay}"
可綁定基礎 class:
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected bool CanExecute
{
get
{
return true;
}
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
財產:
public TestCaseNode TestCases
{
get { return mainWindowModel.TestCases; }
set
{
mainWindowModel.TestCases = value;
SetProperty(ref _testCases, value);
}
}
孩子們:
public ObservableCollection<TestCaseNode> Children { get; set; }
我編輯東西的地方:
SelectedTreeViewItem.SetTestAssessmentForCluster(testAssessment);
OnPropertyChanged("Children");
OnPropertyChanged("TestCases");
OnPropertyChanged(nameof(TestCases));
OnPropertyChanged(nameof(TestCases.Children));
View 沒有任何變化(但是當我在 Visual Studio 中調試它時,我清楚地看到 object 發生了變化)
這行得通,但它使其他事情崩潰:
SelectedTreeViewItem.SetTestAssessmentForCluster(testAssessment);
var tc = TestCases;
TestCases = null;
TestCases = tc;
升級版:
測試用例節點 Class:
public class TestCaseNode : TestCase, IEquatable<TestCaseNode>, IComparable<TestCaseNode>
{
public TestCaseNode Parent { get; set; }
public ObservableCollection<TestCaseNode> Children { get; set; }
public void Add(TestCaseNode node) {...}
public void SetTestAssessmentForCluster(TestAssessment testAssessment, ref TestScores _testScores) {...}
public bool Equals(TestCaseNode other) {...}
public override bool Equals(object obj) {...}
public override int GetHashCode() {...}
public int CompareTo(TestCaseNode other) {...}
}
測試用例 Class:
public class TestCase
{
public string Id { get; set; } = string.Empty;
public string Name { get; set; }
public string Description { get; set; }
public ObservableCollection<TestStep> TestSteps { get; set; }
public TestAssessment TestAssessment { get; set; } = TestAssessment.EMPTY;
}
OnPropertyChanged("TestCases");
必須由包含已更改屬性的 object 頒發。 在您的情況下,您的 class TestCaseNode
將需要調用OnPropertyChanged
方法,以便 Treeview 識別對集合的更改,因為 object 持有集合。 也就是說,更改的不僅僅是一些名為"TestCases"
的屬性,而是特定 object 中的屬性。 原因:您可以在不同的類中擁有多個具有此名稱的屬性。 並且,如果 object 有多個副本,則它們每個都有同名的屬性。
我所做的,這對我有用,是在TestCaseNode
中添加一個名為UpdateProperties()
的公共方法,然后調用OnPropertyChanged("TestCases");
這可確保由正確的 object 發出屬性更新。 然后當我需要更新控件時調用此方法。
還有其他幾種方法可以做同樣的事情,但我發現這是一種簡單直接的方法。 例如,您可以包括 `OnPropertyChanged("TestCases"); 在您的添加方法中。 我沒有這樣做是因為 1) OnPropertyChanged 調用發生得太頻繁,並且 2) 如果沒有 OnPropertyChanged 調用,我可以推遲對控件的更新,直到我完成了幾個或全部 Add 之后。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.