【问题标题】:Binding SelectedItems in ListView to a ViewModel in Windows Phone 8.1将 ListView 中的 SelectedItems 绑定到 Windows Phone 8.1 中的 ViewModel
【发布时间】:2014-12-08 08:41:30
【问题描述】:

我有以下代码:

<ListView SelectionMode="Multiple" ItemsSource="{Binding MyList}" ItemTemplate="{StaticResource MyListTemplate}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

使用以下数据模板:

<Page.Resources>
    <!-- Data Template for the ListView -->
    <DataTemplate x:Key="MyListTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Image Grid.Column="0" Source="{Binding Path=Icon}" />
            <StackPanel Grid.Column="1" Orientation="Vertical">
                    <TextBlock Text="{Binding Path=EntryDate}" TextAlignment="Left" />
                <TextBlock Text="{Binding Path=Url}" TextAlignment="Left" />
                <TextBlock Text="{Binding Path=Text}" TextAlignment="Left" />
            </StackPanel>
        </Grid>
    </DataTemplate>
</Page.Resources>

在我的 ViewModel 中,我有以下内容:

private ObservableCollection<MyModel> myList;
public ObservableCollection<MyModel> MyList {
    get { return myList; }
    set {
        myList = value;
        RaisePropertyChanged("MyList");
    }
}

public IEnumerable<MyModel> SelectedItems {
    get { return MyList == null ? null : MyList.Where(e => e.IsSelected); }
}

在我的模型中,我的 IsSelected 属性包括:

private bool isSelected;
public bool IsSelected {
    get { return isSelected; }
    set { Set(ref isSelected, value); }
}

我可以看到SelectedItems 拥有MyList 拥有的所有元素,但是,当我在 UI 中选择一些元素时,IsSelected 属性没有更新,它们都保持为 false。
那么我在这里做错了什么?

【问题讨论】:

  • 你能显示MyListTemplate吗?
  • 问题已使用 DataTemplate 更新。
  • 您是否在IsSelected 的设置器上设置了断点以检查单击项目时是否调用它?
  • 仅在我第一次填充集合时设置。当我选择/取消选择时,该集合没有被触发,但我不知道为什么。
  • 奇怪,我刚刚在 WPF 中测试过它,它正在工作。无法在 WP8.1 上测试,因为我没有它

标签: c# xaml mvvm windows-phone-8.1


【解决方案1】:

感谢YossiStarz in MSDN Forum,我设法解决了我的问题。所以这是他的解决方案:

问题是你不能在元素上使用 Style 来 SetBinding 你把风格。这是因为样式创建一次 当创建列表视图而不是每个项目容器时。 您实际上所做的是创建一个具有 setter 的样式对象 它的 Value 属性绑定到 IsSelected 的对象 Style 父级的 DataContext(它没有)。这个绑定 发生在 setter 中设置 Value 属性的值。如果它 将成功获得价值,这是它将设置为的值 所有物品的容器。
我有一个解决方案。
首先 最简单的,创建这个帮助类:

public class Helper {
    public static string GetIsSelectedContainerBinding(DependencyObject obj) {
        return (string)obj.GetValue(IsSelectedContainerBindingProperty);
    }

    public static void SetIsSelectedContainerBinding(DependencyObject obj, string value) {
        obj.SetValue(IsSelectedContainerBindingProperty, value);
    }

    // Using a DependencyProperty as the backing store for IsSelectedContainerBinding.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsSelectedContainerBindingProperty =
        DependencyProperty.RegisterAttached("IsSelectedContainerBinding", typeof(string), typeof(helper), new PropertyMetadata(null, IsSelectedContainerBindingPropertyChangedCallback));

    public static void IsSelectedContainerBindingPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        BindingOperations.SetBinding(d, ListViewItem.IsSelectedProperty, new Binding() {
            Source = d,
            Path = new PropertyPath("Content." + e.NewValue),
            Mode = BindingMode.TwoWay
        });
    }
}

现在把setter改成这样:

<Style TargetType="ListViewItem">
    <Setter Property="local:Helper.IsSelectedContainerBinding" Value="IsSelected"/>
</Style>

这应该将 SetBinding 应用于创建的每个容器。

【讨论】:

猜你喜欢
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多