在 SelectedItemChanged 事件中更改 WPF TreeView SelectedItem

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24756011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:09:19  来源:igfitidea点击:

Changing WPF TreeView SelectedItem in SelectedItemChanged event

c#wpfxamltreeview

提问by user1

I currently have a WPF Treeview with a structure of:

我目前有一个 WPF Treeview,其结构为:

--> Group 1 (Hierarchical Group)
   ---> Group 2 (Hierarchical Group)
      ---> Item 1
      ---> Item 2
      ---> Item 3

I currently have a SelectedItemChanged event handler hooked up to this treeview like so

我目前有一个 SelectedItemChanged 事件处理程序像这样连接到这个树视图

private void TreeViewControl_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{

     if (e.NewValue is Item)
     {
         Item item = e.NewValue as Item;
         if (Item != SelectedItem)
         {
             //keep SelectedItem in sync with Treeview.SelectedItem
             SelectedItem = e.NewValue as Item;
         }

     }
     else
     {
         //if the user tries to select an object that isn't an Item (i.e. a group) reselect the first Item in that group
         //This will then cause stack overflow in methods I've tried so far
     }
}

So my question is, how can I keep the SelectedItem of the treeview in sync with my SelectedItem property in my code behind and also how can I reselect an item if the user selects a group?

所以我的问题是,如何使树视图的 SelectedItem 与我后面代码中的 SelectedItem 属性保持同步,以及如果用户选择了一个组,我如何重新选择一个项目?

EDIT:

编辑:

    <TreeView Grid.Row="1" Grid.RowSpan="2"
              ItemContainerStyle="{StaticResource StandardListStyle}"
              ItemTemplate="{StaticResource TreeViewItemTemplate}"
              BorderThickness="1,0,1,1"
              VerticalContentAlignment="Stretch"
              HorizontalAlignment="Stretch"
              ItemsSource="{Binding Teams}"
              SelectedItemChanged="TreeViewControl_SelectedItemChanged"
              Loaded="OnTreeViewLoaded"
              x:Name="TreeViewControl">

where:

在哪里:

Teams = List<HierachicalGroup>;

and where:

以及:

public class HierachicalGroup
{
    public virtual string Name { get; set; }
    public virtual HierachicalGroup[] Children { get; set; }
    public virtual HierachicalGroup Parent { get; set; }
}

and item is:

项目是:

public class Item: HierachicalGroup
{
    public Domain Domain { get; set; }

    public override string Name
    {
        get
        {
            return Domain.DomainName;
        }
    }
}

采纳答案by user1

Ok so this was a lot more complicated than I initially thought.

好吧,这比我最初想象的要复杂得多。

I used this link for help: WPT TreeView ViewModel Pattern

我使用此链接寻求帮助:WPT TreeView ViewModel Pattern

    <TreeView Grid.Row="1" Grid.RowSpan="2"
              ItemTemplate="{StaticResource TreeViewItemTemplate}"
              BorderThickness="1,0,1,1"
              VerticalContentAlignment="Stretch"
              HorizontalAlignment="Stretch"
              ItemsSource="{Binding Teams}"
              SelectedItemChanged="TreeViewControl_SelectedItemChanged"
              Loaded="OnTreeViewLoaded"
              x:Name="TreeViewControl">
        <TreeView.ItemContainerStyle>
            <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>

Where:

在哪里:

 public class HierachicalGroup: INotifyPropertyChanged
    {
        public virtual string Name { get; set; }
        public virtual HierachicalGroup[] Children { get; set; }
        public virtual HierachicalGroup Parent { get; set; }

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    this.OnPropertyChanged("IsSelected");
                }
            }
        }


        private bool _isExpanded;
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    this.OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded && Parent != null)
                    Parent.IsExpanded = true;
            }
        }


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion // INotifyPropertyChanged Members
   }

and:

和:

 public class Item: HierachicalGroup, INotifyPropertyChanged
    {
        public Domain Domain { get; set; }

        public override string Name
        {
            get
            {
                return Domain.DomainName;
            }
            set
            {
                //not doing it :)
            }
        }

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    this.OnPropertyChanged("IsSelected");
                }
            }
        }

        private void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }



        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

and Finally:

最后:

    private void TreeViewControl_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {

        if (e.NewValue is Item)
        {
            Item item = e.NewValue as Item;
            if (Item != SelectedItem)
            {
                //keep SelectedItem in sync with Treeview.SelectedItem
                SelectedItem = e.NewValue as Item;
            }

        }
        else
        {
            var item = e.NewValue as HierarchicalGroup;
            item.IsExpanded = true;
            if (item.Children.Count() > 0)
            {
                if (item.Children[0] is Item)
                {
                    (item.Children[0] as Item).IsSelected = true;
                }
            }
        }
    }

回答by Nitin Joshi

In TreeView.SelectedItemChanged event, we get e.NewValue which is type of TreeViewItem, so I think you can use following code to select an item when it's group is selected.

在 TreeView.SelectedItemChanged 事件中,我们得到了 TreeViewItem 类型的 e.NewValue,因此我认为您可以使用以下代码在选择项目组时选择项目。

var item = (e.NewValue as TreeViewItem);
if (item.Items.Count > 0)
{
    (item.Items[0] as TreeViewItem).IsSelected = true;
}

回答by Sheridan

You haven't really shown enough for a solid answer, but you must have set a collection of some type as the TreeView.ItemsSourceproperty. Therefore allof your items in that collection must beof that type, maybe a base type. You just need to make your SelectedItemproperty the same type as those items in the collection and then you could do this:

您还没有真正展示出足够的可靠答案,但您必须将某种类型的集合设置为TreeView.ItemsSource属性。因此,该集合中的所有项目都必须属于该类型,可能是基本类型。您只需要使您的SelectedItem属性与集合中的那些项目具有相同的类型,然后您就可以执行以下操作:

SelectedItem = e.NewValue as TypeOfItemsInCollection;

Or, you could just add a SelectedGroupItemproperty of type Group(or whatever you need) and do this:

或者,您可以只添加一个SelectedGroupItemtype 属性Group(或您需要的任何属性)并执行以下操作:

if (e.NewValue is Item)
{
    SelectedItem = e.NewValue as Item;
}
else if (e.NewValue is Group)
{
    SelectedGroupItem = e.NewValue as Group;
}