Множественный выбор в WPF Listview и несколько стилей

#c# #wpf #listview #mvvm

#c# #wpf #listview #mvvm

Вопрос:

У меня есть приложение в WPF (MVVM).

  • Я создал модель представления, которая указывает на ObservableCollections, которые будут отображаться в ListView.
  • ListView имеет два пользовательских ресурса представления. ‘GridView’ и ‘TileView’ и кнопки для переключения между ними.

Когда я выбираю несколько элементов и переключаюсь на другой вид, выбранные элементы не синхронизируются … после попытки отладки я думаю, что по какой-то причине при изменении представлений это:

  1. Возвращает значение IsSelected для каждого элемента в списке (это нормально)
  2. Устанавливает (снова ..) элементы, которые только что были установлены (в другом представлении ..) (?)

Разметка:

     <Window.Resources>

    <local:TileView x:Key="ImageView">
        <local:TileView.ItemTemplate >
            <DataTemplate >
                <StackPanel Width="150" VerticalAlignment="Top">
                    <Image Source="{Binding Path=ImagePath}"/>                        
                    <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Path=PhotoReferenceCode}"/>                                                
                </StackPanel>
            </DataTemplate>
        </local:TileView.ItemTemplate>
    </local:TileView>

    <GridView x:Key ="ListView">
        <GridViewColumn Header="Select" Width="100" >
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Grid Width="100">
                        <!--<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" HorizontalAlignment="Center"/>-->
                    </Grid>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
        <GridViewColumn Header="Image" Width="100" >
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Image Source="{Binding Path=ImagePath}" Stretch="UniformToFill" HorizontalAlignment="Center" />
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
        <GridViewColumn Header="Reference Code" Width="100" DisplayMemberBinding="{Binding Path=PhotoReferenceCode}"/>
    </GridView>

</Window.Resources>

<Grid>
    <ListView Margin="0,36,0,0"  View="{Binding  Path=ViewType, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" SelectionMode="Multiple" 
              ItemsSource="{Binding  Path=InfoList, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
            </Style>
        </ListView.ItemContainerStyle>


    </ListView>
    <Button Name="btnListView" Content="ListView" Click="btnListView_Click" HorizontalAlignment="Left" Margin="10,9,0,0" VerticalAlignment="Top" Width="75"/>
    <Button Name="btnImageView" Content="ImageView" Click="btnImageView_Click"  HorizontalAlignment="Left" Margin="99,9,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
  

Класс элемента:

 public class ItemData : INotifyPropertyChanged
{

    #region Members

    private bool _IsSelected;

    public string ImagePath { get; set; }

    public string PhotoReferenceCode { get; set; }

    #endregion

    #region Constractors

    public ItemData()
    {

    }

    public ItemData(bool Is_Sected, string Image_Path, int Item_Carat, string Photo_Reference_Code)
    {
        IsSelected = Is_Sected;
        ImagePath = Image_Path;
        ItemCarat = Item_Carat;
        PhotoReferenceCode = Photo_Reference_Code;
    }

    #endregion

    #region Public

    public bool IsSelected
    {
        get { return _IsSelected; }
        set
        {
            if (this.PropertyChanged != null amp;amp; _IsSelected != value)
            {
                _IsSelected = value; OnPropertyChanged("IsSelected");
            }
        }
    }

    #endregion

    #region Events

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

}
  

Любая помощь будет оценена.

Ответ №1:

Привяжите все выбранные элементы listview к свойству в модели представления, используя привязку TwoWay. Таким образом, ViewModel сохраняет выбранные элементы listview, и поэтому при изменении представления новый стиль listview может выбрать выбранные элементы из ViewModel

Комментарии:

1. <ListView Margin="0,36,0,0" View="{Binding Path=ViewType, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" SelectionMode="Multiple" ItemsSource="{Binding Path=InfoList, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" SelectedItem="{Binding Path=ViewType, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Mode=TwoWay}"> К сожалению, никаких успехов…

2. Почему в вашем коде оба view и SelectedItems привязываются к одному и тому же свойству «viewType»?? View=»{Путь привязки = viewType, RelativeSource={RelativeSource Mode= FindAncestor, AncestorType={x:Type Window}}}» SelectedItem=»{Путь привязки= viewType, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Mode= TwoWay}»>

3. Объявите новое имя свойства и привяжите все выбранные элементы вашего ListView к этому свойству в XAML.

4. хорошо, каков тип «InfoList». вставьте код этого свойства сюда.

5. Хорошо, очевидно, что то, что я сделал, не имеет смысла.. (Я новичок в .net и wpf, это моя вторая неделя …) Я не уверен, что понимаю, что вы говорите… (Просто для ясности, у меня есть только 1 listview с 2 представлениями.) Итак, я объявил новое свойство с именем SelectedItem public ItemData SelectedItem { get { return _SelectedItem; } set{_SelectedItem = value; OnPropertyChanged("SelectedItem");} } и привязал его к свойству SelctedItem в ListView, но оно принимает только один элемент… SelectedItem="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"