Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单击listviewitem中未选定的按钮并获取选定项_C#_Wpf_Listview_Mvvm - Fatal编程技术网

C# 单击listviewitem中未选定的按钮并获取选定项

C# 单击listviewitem中未选定的按钮并获取选定项,c#,wpf,listview,mvvm,C#,Wpf,Listview,Mvvm,我有一个关于listview设置的问题,如下例所示。当我在expander标题中单击下面的按钮时,我也希望选择该项,但我看到的是,当button命令起作用时,所选的项仍然是先前选择的项,而不是我按钮所在的项。单击按钮时如何选择项目 我试着像这样设置一个ControlTemplate,但它不起作用 <Style TargetType="{x:Type ListViewItem}"> <Setter Property="HorizontalContentAlignment"

我有一个关于listview设置的问题,如下例所示。当我在expander标题中单击下面的按钮时,我也希望选择该项,但我看到的是,当button命令起作用时,所选的项仍然是先前选择的项,而不是我按钮所在的项。单击按钮时如何选择项目

我试着像这样设置一个ControlTemplate,但它不起作用

<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");
            }
        }
    }

这非常有效,非常受欢迎,现在我看到了,我同意,这更容易了。