C# 单击listviewitem中未选定的按钮并获取选定项
我有一个关于listview设置的问题,如下例所示。当我在expander标题中单击下面的按钮时,我也希望选择该项,但我看到的是,当button命令起作用时,所选的项仍然是先前选择的项,而不是我按钮所在的项。单击按钮时如何选择项目 我试着像这样设置一个ControlTemplate,但它不起作用C# 单击listviewitem中未选定的按钮并获取选定项,c#,wpf,listview,mvvm,C#,Wpf,Listview,Mvvm,我有一个关于listview设置的问题,如下例所示。当我在expander标题中单击下面的按钮时,我也希望选择该项,但我看到的是,当button命令起作用时,所选的项仍然是先前选择的项,而不是我按钮所在的项。单击按钮时如何选择项目 我试着像这样设置一个ControlTemplate,但它不起作用 <Style TargetType="{x:Type ListViewItem}"> <Setter Property="HorizontalContentAlignment"
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListView ItemsSource="{Binding MyItemSource,
Mode=TwoWay}"
SelectedItem="{Binding MySelectedItem,
Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}">
<Expander.Header>
<Button Command={Binding MyCommand}>Click Me</Button>
</Expander.Header>
<!-- content here -->
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
点击我
我建议在主视图模型中定义一个命令SelectItem
,该命令将要选择的项目作为参数。然后,此命令的执行方法可以设置MySelectedItem
属性,将项目视图模型上的属性IsSelected
设置为true
,并调用项目本身的所有进一步操作(即现在由MyCommand
执行的操作)。使用ViewModel中的选择逻辑和干净的绑定,您甚至不需要使用ListView
,但可以使用普通的ItemsControl
:
然后,XAML如下所示:
<ItemsControl ItemsSource="{Binding MyItemSource}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="{Binding IsSelected}">
<Expander.Header>
<Button Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}, Path=DataContext.SelectItem}"
CommandParameter="{Binding"}>Click Me</Button>
</Expander.Header>
<!-- content here -->
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<ItemViewModel> MyItemsSource { get; private set; }
public ItemViewModel SelectedItem { get... set... }
public ICommand SelectItem { get; private set; }
ctor()...
private void ExecuteSelectItem(ItemViewModel item)
{
SelectedItem = item;
foreach (var i in MyItemsSource) i.IsSelected = false;
item.IsSelected = true;
item.DoSomething();
}
}
点击我
MainViewModel的外观如下所示:
<ItemsControl ItemsSource="{Binding MyItemSource}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="{Binding IsSelected}">
<Expander.Header>
<Button Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}, Path=DataContext.SelectItem}"
CommandParameter="{Binding"}>Click Me</Button>
</Expander.Header>
<!-- content here -->
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<ItemViewModel> MyItemsSource { get; private set; }
public ItemViewModel SelectedItem { get... set... }
public ICommand SelectItem { get; private set; }
ctor()...
private void ExecuteSelectItem(ItemViewModel item)
{
SelectedItem = item;
foreach (var i in MyItemsSource) i.IsSelected = false;
item.IsSelected = true;
item.DoSomething();
}
}
public类主视图模型:INotifyPropertyChanged
{
公共ObservableCollection MyItemsSource{get;private set;}
公共项目视图模型SelectedItem{get…set…}
public ICommand SelectItem{get;private set;}
ctor()。。。
私有void ExecuteSelectItem(ItemViewModel项)
{
选择editem=项目;
foreach(MyItemsSource中的VarI)i.IsSelected=false;
item.IsSelected=true;
项目.DoSomething();
}
}
我总是发现自己使用
ItemsControl
实现几行选择逻辑比处理ListView
选择的混乱绑定更容易。在我看来,实现自定义选择行为(多个项目,只允许某些组合等)是非常直观的。您可以轻松使用IsSelected属性来应用所选项目的自定义样式。您可以在视图模型中尝试类似的操作,在setter中添加if语句:
private object _mySelectedItem;
public object MySelectedItem
{
get { return _mySelectedItem; }
set
{
if (_mySelectedItem != value && value != null)
{
_mySelectedItem = value;
OnPropertyChanged("MySelectedItem");
}
}
}
这非常有效,非常受欢迎,现在我看到了,我同意,这更容易了。