繁体   English   中英

WPF TreeView 绑定不更新视图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM