在ListViewItem的点击一个按钮没被选中并获得选择的项目 [英] Clicking a button in a listviewitem that is not selected and getting selected item

查看:113
本文介绍了在ListViewItem的点击一个按钮没被选中并获得选择的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于列表视图设置如下面的例子问题。当我点击下面的按钮中的扩展头我想选择该项目为好,但我所看到的是,而按钮命令没有工作,选择的项目仍然是previous项目选择,而不是项目我的按钮是如何可以单击该按钮时,我已经选择的项目?

我想建立一个的ControlTemplate这样,但没有奏效。

 <风格的TargetType ={X:类型的ListViewItem}>
    < setter属性=Horizo​​ntalContentAlignmentVALUE =弹力/>
        < setter属性=模板>
            < Setter.Value>
                <的ControlTemplate的TargetType ={X:类型的ListViewItem}>
                    <内容presenter的Horizo​​ntalAlignment ={TemplateBinding Horizo​​ntalContentAlignment}VerticalAlignment ={TemplateBinding VerticalContentAlignment}SnapsToDevicePixels ={TemplateBinding SnapsToDevicePixels}/>
                    < ControlTemplate.Triggers>
                        <触发属性=IsKeyboardFocusWithinVALUE =真>
                            < setter属性=IsSelectedVALUE =真/>
                        < /触发>
                    < /ControlTemplate.Triggers>
                < /控件模板>
            < /Setter.Value>
        < /二传手>
    < /样式和GT;
< ListView控件的ItemsSource ={结合MyItemSource,
                                        模式=双向}
                  的SelectedItem ={结合MySelectedItem,
                                         模式=双向}>
    < ListView.ItemTemplate>
        <&DataTemplate的GT;
            <扩展IsExpanded ={绑定的RelativeSource = {的RelativeSource模式= FindAncestor,AncestorType = {X:类型ListViewItem的}},路径= IsSelected}>
                < Expander.Header>
                    <按钮命令= {结合MyCommand}>点击ME< /按钮>
                < /Expander.Header>
                <! - 这里的内容 - >
            < /扩展>
        < / DataTemplate中>
    < /ListView.ItemTemplate>
< /&的ListView GT;


解决方案

我会建议在主视图模型定义命令的SelectItem 这需要将被选择的项目作为参数。那么该命令的执行方法可以设置 MySelectedItem 属性,属性 IsSelected 在项目视图模型设置为真正并调用了项目本身的所有进一步的行动(即什么现在由 MyCommand )。随着在视图模型和一个干净的选择逻辑绑定你甚至不需要使用的ListView 可言,但能坚持到纯的ItemsControl

然后XAML看起来是这样的:

 <的ItemsControl的ItemsSource ={结合MyItemSource}>
    < ItemsControl.ItemTemplate>
        <&DataTemplate的GT;
            <扩展IsExpanded ={结合IsSelected}>
                < Expander.Header>
                    <按钮命令={绑定的RelativeSource = {的RelativeSource模式= FindAncestor,AncestorType = ItemsControl的},路径= DataContext.SelectItem}
                            CommandParameter ={绑定}>点击ME< /按钮>
                < /Expander.Header>
                <! - 这里的内容 - >
            < /扩展>
        < / DataTemplate中>
    < /ItemsControl.ItemTemplate>
< / ItemsControl的>

该MainViewModel会是这个样子:

 公共类MainViewModel:INotifyPropertyChanged的
{
    公众的ObservableCollection< ItemViewModel> MyItemsSource {搞定;私人集; }    公共ItemViewModel的SelectedItem {得到...设置...}    公众的ICommand的SelectItem {搞定;私人集; }    构造函数()...    私人无效ExecuteSelectItem(ItemViewModel项)
    {
        的SelectedItem =项目;
        的foreach(VAR我在MyItemsSource)i.IsSelected = FALSE;
        item.IsSelected = TRUE;
        item.DoSomething();
    }
}

我一直觉得它​​的方式更容易使用的ItemsControl 工具选择逻辑的几行自己,而不是处理的选择<$凌乱绑定C $ C>的ListView 。在我看来,这是一个相当直观的实现自定义选择行为(多个项目,只允许特定的组合等)。您可以使用 IsSelected 属性轻松应用所选项目的自定义样式。

I have a question about a listview setup like the example below. When I click the button below in the expander header I want that item to be selected as well, but what I'm seeing is while the button command does work, the item selected is still the previous item selected, not the item my button is in. How can I have the Item selected when the button is clicked?

I tried setting up a ControlTemplate like this, but it did not work.

<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>

解决方案

I would suggest defining a command SelectItem in the main ViewModel which takes the item which is to be selected as a parameter. The execution method of this command can then set the MySelectedItem property, set a property IsSelected on the item ViewModel to true and invoke all further actions on the item itself (i.e. what is now executed by MyCommand). With the selection logic in the ViewModel and a clean binding you don't even need to use ListView at all but can stick to a plain ItemsControl:

The XAML then looks like this:

<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>

The MainViewModel would look something like this:

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

I have always found it way easier to use ItemsControl an implement the few lines of selection logic myself, instead of dealing with the messy binding of the selection of a ListView. In my opinion it is a quite intuitive to implement custom selection behavior (multiple items, allowing only certain combinations, etc.). You can use the IsSelected property easily to apply a custom styling of selected items.

这篇关于在ListViewItem的点击一个按钮没被选中并获得选择的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆