Binding SelectedItems in ListView to a ViewModel in Windows Phone 8.1

可紊 提交于 2020-01-31 17:58:24

问题


I have the following code:

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

With the following DataTemplate:

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

In my ViewModel I have the following:

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

And in my Model I have among others, my IsSelected property:

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

I can see that the SelectedItems has all the elements that MyList has, however, when I select a few in the UI, the property IsSelected is not updated, they all remain false.
So what am I doing wrong here?


回答1:


Thanks to YossiStarz in MSDN Forum, I managed to solve my problem. So here's his solution:

The problem is that you cant use Style to SetBinding on the element that you put the style on. This is because the style is created once when the listview is created and not for each of the item containers. what you actualy did, is creating a style object that have a setter object that it's Value property is bounded to the IsSelected of the DataContext of the Style parent (witch it doesn't have). This binding occurs to set the value of the Value property in the setter. If it would have succeed to get value, this was the value it would set to all of the items containers.
I have a solution for you.
First and the simplest, create this helper class:

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

Now change the setter to be like this:

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

This should apply SetBinding to each container that is created.



来源:https://stackoverflow.com/questions/26345820/binding-selecteditems-in-listview-to-a-viewmodel-in-windows-phone-8-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!