ListViewItem的IsSelected绑定-适用于WPF,但不适用于WinRT

10
我想把ListViewItem的IsSelected属性绑定到ViewModel中的一个属性。在WPF中可以正常工作,但在Windows RT中,IsSelected属性从未被设置。
public class Item : INotifyPropertyChanged
{
    private readonly string name;
    private bool isSelected;
    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsSelected
    {
        get { return isSelected; }
        set { isSelected = value; RaisePropertyChanged("IsSelected"); }
    }

    public string Name { get { return name; } }

    public Item(string name)
    {
        this.name = name;
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class ViewModel
{
    private readonly ObservableCollection<Item> items = new ObservableCollection<Item>(Enumerable.Range(0, 10).Select(p => new Item(p.ToString())));
    public ObservableCollection<Item> Items { get { return items; } }
}

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        DataContext = new ViewModel();
    }
}

xaml:

<StackPanel Orientation="Horizontal">
    <ListView ItemsSource="{Binding Path=Items}" SelectionMode="Multiple">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Name}"/>
         </DataTemplate>
     </ListView.ItemTemplate>
</StackPanel>

我能够点击屏幕上的项目,但是IsSelected属性并没有传播到ViewModel中。你有什么想法吗?

2个回答

4
一个好的且简单的方法是继承ListView类。
public class MyListView : ListView
    {
        protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            // ...
            ListViewItem listItem = element as ListViewItem;
            Binding binding = new Binding();
            binding.Mode = BindingMode.TwoWay;
            binding.Source = item;
            binding.Path = new PropertyPath("Selected");
            listItem.SetBinding(ListViewItem.IsSelectedProperty, binding);
        }
    }

另外,似乎你也可以使用WinRT XAML Toolkit来完成这个任务。

<ListView
            x:Name="lv"
            Grid.Row="1"
            Grid.Column="1"
            SelectionMode="Multiple"
            HorizontalAlignment="Left"
            Width="500">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock
                        Extensions:ListViewItemExtensions.IsSelected="{Binding IsSelected}"
                        Extensions:ListViewItemExtensions.IsEnabled="{Binding IsEnabled}"
                        Text="{Binding Text}"
                        Margin="15,5"
                        FontSize="36" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

个人而言,我使用了第一种方法,因为它更灵活,而且我需要绑定几个自动化属性。
感谢ForInfo和ehuna: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/9a0adf35-fdad-4419-9a34-a9dac052a2e3/listviewitemisselected-data-binding-in-style-setter-is-not-working

我正在使用WinRT Xaml Toolkit扩展。它正常工作。谢谢。 - HelpMatters
Xaml 工具包对我似乎只能单向工作,即使使用 Mode=TwoWay。如果我在 ListView 中选择了某些内容,它也不会更新 ViewModel 吗? - Stijn Tallon

3

截至Windows 8.0,WinRT完全不支持设置器中的绑定。请搜索解决方法。


你能提供一个链接吗?我不知道该搜什么。 - David Klimek
请查看我对这个问题的回答:https://dev59.com/W2ct5IYBdhLWcg3wvf7J - Filip Skakun
我正在使用WinRT Xaml Toolkit扩展。它能够正常工作。谢谢。 - HelpMatters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接