我目前有一个结构为:
的WPF Treeview--> Group 1 (Hierarchical Group)
---> Group 2 (Hierarchical Group)
---> Item 1
---> Item 2
---> Item 3
我目前有一个这样的树视图连接的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
}
}
所以我的问题是,如何在我的代码中保持treeview的SelectedItem与我的SelectedItem属性同步,以及如果用户选择一个组,我该如何重新选择一个项?
修改
<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">
其中:
Teams = List<HierachicalGroup>;
以及其中:
public class HierachicalGroup
{
public virtual string Name { get; set; }
public virtual HierachicalGroup[] Children { get; set; }
public virtual HierachicalGroup Parent { get; set; }
}
和项目是:
public class Item: HierachicalGroup
{
public Domain Domain { get; set; }
public override string Name
{
get
{
return Domain.DomainName;
}
}
}
答案 0 :(得分:3)
在TreeView.SelectedItemChanged事件中,我们得到了一个TreeViewItem类型的e.NewValue,所以我认为你可以使用下面的代码来选择一个项目。
var item = (e.NewValue as TreeViewItem);
if (item.Items.Count > 0)
{
(item.Items[0] as TreeViewItem).IsSelected = true;
}
答案 1 :(得分:1)
您还没有真正展示出足够的答案,但您必须将某种类型的集合设置为TreeView.ItemsSource
属性。因此,该集合中所有项目必须是该类型的,可能是基本类型。您只需要使SelectedItem
属性与集合中的项目类型相同,然后您就可以执行此操作:
SelectedItem = e.NewValue as TypeOfItemsInCollection;
或者,您可以添加SelectedGroupItem
类型的Group
属性(或您需要的任何内容)并执行此操作:
if (e.NewValue is Item)
{
SelectedItem = e.NewValue as Item;
}
else if (e.NewValue is Group)
{
SelectedGroupItem = e.NewValue as Group;
}
答案 2 :(得分:1)
好的,这比我最初想的要复杂得多。
我使用此链接获取帮助: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>
其中:
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
}
和
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));
}
}
最后:
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;
}
}
}
}