#c# #wpf #listview
#c# #wpf #listview
Вопрос:
Я создал минималистичный образец, используя ListView с тремя элементами в нем и ContentControl рядом с ним, который отображает выбранный элемент ListViewItem. Что меня озадачивает, так это то, что когда я выбираю элемент, он отображается правильно в ContentControl, но становится таким маленьким в ListView, как если бы он исчезал. Кто-нибудь может объяснить мне, что здесь происходит?
Главное окно с ListView и ContentControl в сетке. ContentControl.Содержимое привязывается к выбранному элементу ListView.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding ListViewItems}" SelectedItem="{Binding SelectedListViewItem}"/>
<ContentControl Grid.Column="1" Content="{Binding SelectedListViewItem}"/>
</Grid>
</Window>
В MainWindow для DataContext установлено значение MainWindowViewModel
using System.Windows;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
MainWindowViewModel реализует INotifyPropertyChanged и содержит элементы ListViewItems, а также SelectedListViewItem.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
ListViewItems = new ObservableCollection<Control>()
{
new TextBox(){ Text = "TB1", IsReadOnly = true },
new TextBox(){ Text = "TB2", IsReadOnly = true },
new TextBox(){ Text = "TB3", IsReadOnly = true },
};
}
private ObservableCollection<Control> _listViewItems;
private Control _selectedListViewItem;
public ObservableCollection<Control> ListViewItems
{
get
{
return _listViewItems;
}
set
{
if (SetProperty(ref _listViewItems, value))
{
}
}
}
public Control SelectedListViewItem
{
get
{
return _selectedListViewItem;
}
set
{
if (SetProperty(ref _selectedListViewItem, value))
{
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual bool SetProperty<T>(ref T backingField, T newValue, [CallerMemberName] string propertyName = null)
{
var ret = false;
if (!EqualityComparer<T>.Default.Equals(backingField, newValue))
{
backingField = newValue;
OnPropertyChanged(propertyName);
ret = true;
}
return ret;
}
}
Я знаю, что ViewModel не должен содержать никаких ссылок на какое-либо представление. Однако из минимальной выборки это было необходимо. Вопрос для меня в том, почему элементы ListViewItems «исчезают».
Я нажал на первый элемент ListViewItem, TB1. Он отображается в contentcontrol справа, но ListView теперь выглядит странно. Я могу повторить это и для других элементов ListViewItems.
Это происходит после нажатия также на TB2, а затем, наконец, на TB3
Ответ №1:
Ваша проблема в том, что элемент управления может появиться только один раз в пользовательском интерфейсе.
Вы создаете элементы управления в коде.
Когда вы выбираете один, он берется с того места, где вы его выбрали, и перемещается туда, где вы его привязали.
Не создавайте элементы управления в коде.
Используйте mvvm.
Создайте данные (viewmodels ) и привяжите к пользовательскому интерфейсу.
Datatemplate эти данные в элементы управления.
Комментарии:
1. Спасибо, это очень хорошо объясняет то, что я наблюдал. Я не знал об этом движущемся поведении.