我遇到了IsSelected属性的问题。它不会将视图中的值发送到视图模型。我在下面发布了我的代码 视图模型:
public class Viewmodel : INotifyPropertyChanged
{
private ObservableCollection<int> seznam;
public ObservableCollection<int> Seznam
{
get { return seznam; }
set
{
seznam = value;
}
}
public Viewmodel()
{
Seznam = new ObservableCollection<int>();
for (int i = 0; i < 3; i++)
{
Seznam.Add(i);
}
}
bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
查看:
<TreeView ItemsSource="{Binding Seznam}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
它仍然没有停在断点,我把它放在了{return isSelected; }
答案 0 :(得分:0)
根据您更新的帖子,很明显您尚未正确实施您的视图模型。特别是,您的TreeView.ItemsSource
绑定到唯一视图模型的Seznam
属性。这是int
值的集合。
这意味着您尝试绑定到TreeView
属性的IsSelected
中每个项容器的数据上下文是int
值。当然,int
值甚至不具有IsSelected
属性。
(顺便说一下,我对your claim that "There are no binding errors"持怀疑态度。如果查看调试输出,你当然应该看到绑定错误,试图绑定到不存在的IsSelected
属性。)
考虑一下这一点:假设item容器确实设法绑定到Viewmodel.IsSelected
属性。你认为有多少个项目容器?您认为有多少Viewmodel
个实例?您应该相信有许多项目容器,即您的收藏中的每个项目一个。并且只有Viewmodel
的一个实例。那么,所有这些项目将如何?选择状态甚至映射到单个Viewmodel.IsSelected
属性?
执行此操作的正确方法是为集合创建单独的视图模型对象,其中包含int
值的属性,以及IsSelected
和{{1}的属性} states(因为你最初提到过想要两者)。
这是我之前写的一个例子,只是为了向自己证明通常的方法可以按预期工作。根据您的需要调整它不应该有任何麻烦......
每件商品视图模型:
IsExpanded
窗口的主视图模型:
class TreeItemViewModel : NotifyPropertyChangedBase
{
public ObservableCollection<TreeItemViewModel> Items { get; }
= new ObservableCollection<TreeItemViewModel>();
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set { _UpdateField(ref _isSelected, value, _OnBoolPropertyChanged); }
}
private bool _isExpanded;
public bool IsExpanded
{
get { return _isExpanded; }
set { _UpdateField(ref _isExpanded, value, _OnBoolPropertyChanged); }
}
private void _OnBoolPropertyChanged(bool obj)
{
_RaisePropertyChanged(nameof(FullText));
}
private string _text;
public string Text
{
get { return _text; }
set { _UpdateField(ref _text, value, _OnTextChanged); }
}
private void _OnTextChanged(string obj)
{
_RaisePropertyChanged(nameof(FullText));
}
public string FullText
{
get { return $"{Text} (IsSelected: {IsSelected}, IsExpanded: {IsExpanded})"; }
}
}
XAML for window:
class MainViewModel : NotifyPropertyChangedBase
{
public ObservableCollection<TreeItemViewModel> Items { get; }
= new ObservableCollection<TreeItemViewModel>();
public ICommand ClearSelection { get; }
public MainViewModel()
{
ClearSelection = new ClearSelectionCommand(this);
}
class ClearSelectionCommand : ICommand
{
private readonly MainViewModel _parent;
public ClearSelectionCommand(MainViewModel parent)
{
_parent = parent;
}
#pragma warning disable 67
public event EventHandler CanExecuteChanged;
#pragma warning restore 67
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_parent._ClearSelection();
}
}
private void _ClearSelection()
{
_ClearSelection(Items);
}
private static void _ClearSelection(IEnumerable<TreeItemViewModel> collection)
{
foreach (TreeItemViewModel item in collection)
{
_ClearSelection(item.Items);
item.IsSelected = false;
item.IsExpanded = false;
}
}
}
为了完整......
<Window x:Class="TestSO44513864TreeViewIsSelected.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:l="clr-namespace:TestSO44513864TreeViewIsSelected"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<l:MainViewModel>
<l:MainViewModel.Items>
<l:TreeItemViewModel Text="One">
<l:TreeItemViewModel.Items>
<l:TreeItemViewModel Text="One A"/>
<l:TreeItemViewModel Text="One B"/>
</l:TreeItemViewModel.Items>
</l:TreeItemViewModel>
<l:TreeItemViewModel Text="Two"/>
<l:TreeItemViewModel Text="Three"/>
</l:MainViewModel.Items>
</l:MainViewModel>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content="Clear Selection" Command="{Binding ClearSelection}"
HorizontalAlignment="Left"/>
<TreeView ItemsSource="{Binding Items}" Grid.Row="1">
<TreeView.ItemContainerStyle>
<p:Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
</p:Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="l:TreeItemViewModel"
ItemsSource="{Binding Items}">
<TextBlock Text="{Binding FullText}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>
实施的样板基类:
INotifyPropertyChanged
答案 1 :(得分:-1)
不要在树中的每个节点上使用IsSelected,而是在TreeView本身上使用TreeView.SelectedItem。从这里你可以绑定,但属性是readonly。