列表视图被选中 [英] ListView isSelected

查看:22
本文介绍了列表视图被选中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 xaml 中有一个列表视图,我用这样的项目填充:

Listdicts = DataLayer.Manager.getDictionaries();如果(听写!= null){foreach (DataLayer.Models.Dictionary dicts 中的 dict){this.itemListView.Items.Add(dict);}}

我的 DataLayer.Models.Dictionary 对象有一个 isSelected 属性以及一个 Name 和一个 SubName.

Name 和 SubName 在模板中工作正常,但如何在用户单击项目时选择并更新项目?

谢谢!

我的 xaml 现在看起来像这样,但项目仍然没有被选中

 <ListView.ItemContainerStyle><Style TargetType="ListViewItem"><Setter Property="IsSelected" Value="{Binding Source=Selected,Mode=TwoWay}"/></风格></ListView.ItemContainerStyle><ListView.ItemTemplate><数据模板><网格边距="6"><Grid.ColumnDefinitions><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><StackPanel Grid.Column="0" Margin="0,0,0,0"><TextBlock Text="{绑定名称}"/><TextBlock Text="{Binding SubName}" Style="{StaticResource CaptionTextStyle}" TextWrapping="Wrap"/></StackPanel></网格></数据模板></ListView.ItemTemplate></ListView>

解决方案

刚刚注意到这个问题实际上并没有被标记为 WPF;但我希望它仍然适用.

WPF 本质上是 MVVM.在后面的代码中直接操作控件通常不是一个好主意.因此,建议创建一个名为 ViewModel 的视图友好"模型;

现在可以在代码隐藏中对选择更改做出反应,但这会将逻辑与视图混合.

更新以包括检测任何字典中的变化的能力(包括选定的变化时)

您可以研究一下以简化它

希望这会有所帮助.

I have an listview in my xaml that i populate with items like this:

List<DataLayer.Models.Dictionary> dicts = DataLayer.Manager.getDictionaries();

if (dicts != null)
{
    foreach (DataLayer.Models.Dictionary dict in dicts)
    {
         this.itemListView.Items.Add(dict);
    }
}

My DataLayer.Models.Dictionary object have an isSelected property along with a Name and a SubName.

Name and SubName works fine in the template but how can i go about getting the item to be selected and also updated when user clicks an item?

Thanks!

Edit:

My xaml now looks like this, but the item is still not selected

    <ListView
        x:Name="itemListView"
        TabIndex="1"
        Grid.Row="1"
        Margin="0,60,0,0"
        Padding="0,0,0,0"
        IsSwipeEnabled="False"
        ScrollViewer.VerticalScrollBarVisibility="Hidden"
        SelectionChanged="itemListView_SelectionChanged_1"
        SelectionMode="Multiple"
        FontFamily="Global User Interface">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="IsSelected" Value="{Binding Source=Selected,Mode=TwoWay}"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Margin="6">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Grid.Column="0" Margin="0,0,0,0">
                        <TextBlock Text="{Binding Name}"/>
                        <TextBlock Text="{Binding SubName}" Style="{StaticResource CaptionTextStyle}" TextWrapping="Wrap"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

解决方案

[Edit] Just noticed this question isn't actually tagged WPF; but I hopefully it still applies.

WPF is inherently MVVM. Directly manipulating controls in code behind is generally not a good idea. So it is advised to create a "view-friendly" model called a ViewModel; See Here. Also for bindings to be of any use, in a changing environment, you must inform of changes to properties and or collections, so that controls can be updated.

First and formost you have a collection of dictionaries, So you create this collection such that it can notify of changes; ObservableCollection can do that. As a general rule of thumb any collection used by WPF you should just use an ObservableCollection, and/or derive from it.

so here is compete working example:

Bare in mind I'm using FODY to inject my PropertyChanged raisers; See done manually

public class Dict : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string Name { get; set; }
    public string SubName { get; set; }
    public bool Selected { get; set; }
}

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<Dict> Dictionaries { get; set; }

    public ViewModel()
    {
        Dictionaries = new ObservableCollection<Dict>()
        {
            new Dict()
                {
                    Name = "English",
                    SubName = "en",
                    Selected = false,
                },

                new Dict()
                {
                    Name = "English-British",
                    SubName = "en-uk",
                    Selected = true
                },

                new Dict()
                {
                    Name = "French",
                    SubName = "fr",
                    Selected = true
                }
        };

        Dictionaries.CollectionChanged += DictionariesCollectionChanged;
    }

    private void DictionariesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch(e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                foreach(var dict in e.NewItems.Cast<Dict>())
                    dict.PropertyChanged += DictionaryChanged;
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (var dict in e.OldItems.Cast<Dict>())
                    dict.PropertyChanged -= DictionaryChanged;
                break;
        }
    }

    private void DictionaryChanged(object sender, PropertyChangedEventArgs e)
    {
        Dict dictionary = (Dict)sender;

        //handle a change in Dictionary
    }
}

With this you can add or remove objects at any time, although here I am just initializing them in the constructor.

Then you would have this in your window or control. I've included the namespaces to make it more self-contained; but this would be for WPF namespaces.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:WpfApplication1">

    <Window.Resources>
        <local:ViewModel x:Key="viewmodel"/>
    </Window.Resources>

    <ListView
        x:Name="itemListView"
        DataContext="{StaticResource ResourceKey=viewmodel}"
        ItemsSource="{Binding Path=Dictionaries}"
        SelectionMode="Multiple">

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="IsSelected" Value="{Binding Path=Selected, Mode=TwoWay}"/>
            </Style>
        </ListView.ItemContainerStyle>

        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Margin="6">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Grid.Column="0" Margin="0,0,0,0">
                        <TextBlock Text="{Binding Name}"/>
                        <TextBlock Text="{Binding SubName}" TextWrapping="Wrap"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Window>

If you don't use ObservableCollection for your collection, then start adding elements to it after WPF has be loaded-up, it will never notify the binding manager that the ListView should be updated.

The above on start up:

you can easily see that the underlying Dictionaries collection is being changed (i.e.its not just the ListView), by overriding the returned value from selected:

public bool Selected { get { return true; } set {/* do nothing*/ }}

Which means everything is always selected, even if you try to deselect it in the view. It will always look like this:

Styling is a different issue, the list looks different if it doesn't have focus. See Here

Now reacting to selection changes could be done in the code-behind, but that would be mixing logic with view.

[Edit] updated to include ability to detect changes in any Dict (including when selected changes)

You could look into this to simplify it

Hope this helps.

这篇关于列表视图被选中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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