#c# #wpf #listview #mvvm
#c# #wpf #listview #mvvm
Вопрос:
У меня есть приложение в WPF (MVVM).
- Я создал модель представления, которая указывает на ObservableCollections, которые будут отображаться в ListView.
- ListView имеет два пользовательских ресурса представления. ‘GridView’ и ‘TileView’ и кнопки для переключения между ними.
Когда я выбираю несколько элементов и переключаюсь на другой вид, выбранные элементы не синхронизируются … после попытки отладки я думаю, что по какой-то причине при изменении представлений это:
- Возвращает значение IsSelected для каждого элемента в списке (это нормально)
- Устанавливает (снова ..) элементы, которые только что были установлены (в другом представлении ..) (?)
Разметка:
<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}}}"