我的 treeView 填充了一个奇怪的 children :WPF MVVM

My treeView populate a strange children : WPF MVVM

我在这个非常好的帮助下构建了一个treeView WPF MVVM article 然后我为某个节点创建了一个上下文菜单,允许我从选定的 parent.

添加 children

问题是,如果我点击 "Add" 而没有手动展开所选节点 (parent),除了预期生成的节点之外,还会自动创建一个奇怪的 child当点击 "Add".

我试图检测问题,所以我更改了下面的代码:

<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />

至:

<Setter Property="IsExpanded" Value="True" />

下面的图 1 显示了此测试的结果,或者图 2 显示了我的 treeView 必须显示的内容。

Rq: 我使用了article 中的图像,我谈到了它。此外,我使用了文章中描述的相同方法(包括 class TreeViewItemViewModel.cs )

<TreeView ItemsSource="{Binding Regions}" IsEnabled="{Binding EnableTree}" > <TreeView.ItemContainerStyle> <!-- This Style binds a TreeViewItem to a TreeViewItemViewModel. --> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> <Setter Property="FontWeight" Value="Normal" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontWeight" Value="Bold" /> </Trigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle> <TreeView.Resources> <ContextMenu x:Key="AddCity" ItemsSource="{Binding AddCityItems}"/> <HierarchicalDataTemplate DataType="{x:Type local:StateViewModel}" ItemsSource="{Binding Children}" > <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource AddCity}"> <Image Width="16" Height="16" Margin="3,0" Source="Images\Region.png" /> <TextBlock Text="{Binding RegionName}" /> </StackPanel> </HierarchicalDataTemplate> </TreeView.Resources>

`public class 状态视图模型:TreeViewItemViewModel {

   readonly State _state;
   public ICommand AddCityCommand { get; private set; }
   public List<MenuItem> AddCityItems { get; set; }

    public StateViewModel(State state, RegionViewModel parentRegion)
        : base(parentRegion, true)
    {
        _state = state;
        AddCityItems = new List<MenuItem>();
        AddCityCommand = new DelegateCommand<CancelEventArgs>(OnAddCityCommandExecute, OnAddCityCommandCanExecute);
        AddCityItems.Add(new MenuItem() { Header = "Add City", Command = AddCityCommand });
    }

    public string StateName
    {
        get { return _state.StateName; }
    }

    protected override void LoadChildren()
    {
        foreach (City city in Database.GetCities(_state))
            base.Children.Add(new CityViewModel(city, this));
    }


    bool OnAddCityCommandCanExecute(CancelEventArgs parameter)
    {
        return true;
    }

    public void OnAddCityCommandExecute(CancelEventArgs parameter)
    {
        var myNewCity = new city();
        Children.Add(new CityViewModel(myNewCity, this));
    }
}`

顺便说一句,如果我展开我的 parent 节点然后单击添加城市,我会得到预期的结果,但如果我不展开 parent 节点并单击上下文菜单我有除了我要创建的 child

之外,还创建了另一个 child

编辑 我将下面的语句添加到我的 add() 方法中,现在我没有任何问题:

public void OnAddCityCommandExecute(CancelEventArgs parameter)
    {
        var myNewCity = new city();
        Children.Add(new CityViewModel(myNewCity, this));
        //the modif
        this.Children.Remove(DummyChild);
    }

我可以看到你代码中的错误。

重现步骤如下:

  1. 在状态节点(永远不要先展开)
  2. 如果不预先扩展 Child,您的 StateViewModel 的 Children 包含一个 DummyChild。
  3. 在列表中添加了 1 个新城市,这导致 HasDummyChild 无法工作,因为 Children 的列表
  4. 中的计数现在是 2
  5. 然后当你尝试展开节点时查看结果。您的树列表将包含 DummyChild,这是一个基础 class,它搞砸了一切

所以,基本上这就是为什么 "Expand" first 是问题的关键,因为当时 HasDummyChild 仍在工作,因为它比较 .Count == 1。树不会删除如果您向列表中添加一个额外的 child 使 .Count == 2.

从您的 Children 列表中删除 DummyChild

请求的附加信息

只需将 HasDummyChild 更改为以下内容

    public bool HasDummyChild
    {
        //get { return this.Children.Count == 1 && this.Children[0] == DummyChild; }
        get { return Children.Any() && Children.Contains(DummyChild); }
    }