#c# #.net #wpf #mvvm-light #wpfdatagrid
#c# #.net #wpf #mvvm-light #wpfdatagrid
Вопрос:
Разработка WPF
приложения с использованием MVVMLight
.
Мой Model
состоит из Attribute
класса и DataSet
класса с ObservableCollection<Attribute>
свойством по имени Attributes
.
У My MainViewModel
есть DataSet
свойство.
В моем, MainView
для DataContext
которого он MainViewModel
установлен на DataGrids
, у меня их два, и у меня есть два,,. У одного есть ItemsSource
привязка к DataSet.Attributes
, которая работает нормально:
<DataGrid CanUserAddRows="false" AutoGenerateColumns="false" ItemsSource="{Binding DataSet.Attributes}">
//some DataGrid columns here
Я хочу, чтобы вторая DataGrid
отображала некоторые дополнительные свойства на основе SelectedItem
первой сетки данных, поэтому я сделал следующее:
1) добавлено SelectedAttribute
свойство типа Attribute
в моем MainViewModel
:
private Attribute selectedAttribute;
public Attribute SelectedAttribute
{
get { return selectedAttribute; }
set
{
if (selectedAttribute == value)
{
return;
}
selectedAttribute = value;
RaisePropertyChanged(() => SelectedAttribute);
}
}
2) изменил мой первый, DataGrid
чтобы привязать его SelectedItem
к SelectedAttribute
:
<DataGrid CanUserAddRows="false" AutoGenerateColumns="false" ItemsSource="{Binding DataSet.Attributes}" SelectedItem="{Binding SelectedAttribute}">
3) Обновление 1 присвоило ItemsSource
второму DataGrid
значение SelectedAttribute
и создало столбец, привязанный к Categories
свойству SelectedAttribute
, которое является ObservableCollection<string>
:
<DataGrid SelectionMode="Single" EnableColumnVirtualization="True" AutoGenerateColumns="false" ItemsSource="{Binding Main.SelectedAttribute}">
<DataGrid.Columns>
<DataGridTextColumn Header="categories" Width="auto" Binding="{Binding Main.SelectedAttribute.Categories}" />
</DataGrid.Columns>
</DataGrid>
4) в моем случае MainViewModel
после DataSet.Attributes
заполнения я устанавливаю SelectedAttribute
значение первого Attribute
в коллекции (просто в качестве теста):
SelectedAttribute = DataSet.Attributes[0];
Как только я запускаю это, первая DataGrid
загружается нормально, но ни один элемент не выбран, а вторая DataGrid
ничего не показывает. Что я делаю не так?
Комментарии:
1. SelectedAttribute — это отдельный объект, и вы пытаетесь привязать его к сетке данных, для которой необходим источник данных, реализующий IEnumerable. Попробуйте сделать SelectedAttribute наблюдаемой коллекцией и применить только один элемент в коде.
2. привет, Пол, второй столбец
DataGrid
фактически привязан кObservableCollection<string>
свойствуAttribute
, см. Обновленный пост выше.
Ответ №1:
ItemsSource сетки должен быть IEnumerable. Итак, это:
ItemsSource="{Binding Main.SelectedAttribute}"
не сработает, потому что SelectedAttribute является экземпляром класса, а не каким-то списком.
Вы также привязываете что-то, что предположительно реализует IEnumerable (категории), к DataTextColumn, что также неверно; привязка столбца сетки должна быть скалярным свойством.
РЕДАКТИРОВАТЬ: Вы не сможете напрямую привязать столбцы в сетке к трем отдельным наблюдаемым коллекциям; вам нужно будет создать новый класс модели для хранения данных, которые вы хотите отобразить в сетке, например:
public class SomeGridItem
{
public string Category {get; set;}
public string SecondProp {get; set;}
public string ThirdProp [get; set;}
}
Затем добавьте новое свойство в вашу модель представления — это то, к чему вы будете привязывать сетку:
public ObservableCollection<SomeGridItem> Blahs {get; set;}
Затем, когда SelectedAttribute изменится, вам нужно будет заполнить пустые места. Вы могли бы сделать это в параметре установки свойств для SelectedAttribute (вероятно, проще всего), или вы могли бы отреагировать на событие PropertyChanged для SelectedAttribute. Это псевдокод, но он должен дать вам представление о том, что нужно сделать.
Blah.Clear();
for (var i = 0; i < SelectedAttribute.Categories.Count; i ) {
Blahs.Add(new SomeGridItem() {
Category = SelectedAttribute.Categories[i],
SecondProp = SelectedAttribute.SecondCollection[i],
ThirdProp = SelectedAttribute.ThirdCollection[i]
});
}
Затем привязать к вашей сетке.
<DataGrid SelectionMode="Single" EnableColumnVirtualization="True" AutoGenerateColumns="false" ItemsSource="{Binding Main.Blahs}">
<DataGrid.Columns>
<DataGridTextColumn Header="categories" Width="auto" Binding="{Binding Category}" />
<DataGridTextColumn Header="categories" Width="auto" Binding="{Binding SecondProp}" />
<DataGridTextColumn Header="categories" Width="auto" Binding="{Binding ThirdProp}" />
</DataGrid.Columns>
</DataGrid>
Комментарии:
1. @paul-abbott-wa-us, это три столбца для трех
ObservableCollection
свойствAttribute
(Categories
и еще 2). Вот почему я пытался привязатьItemsSource
кMain.SelectedAttribute
2. Эти три наблюдаемые коллекции гарантированно будут содержать одинаковое количество элементов? И они связаны по позиции — например, значение Categories[0] соответствует значению SecondCollection[0] и ThridCollection[0]?
3. @paul-abbott-wa-us да по обоим вопросам
4. думаю, я понял, Пол, спасибо, я попробую ваше решение. Однако я не понимаю, почему я не могу напрямую привязать три столбца в сетке к трем отдельным наблюдаемым коллекциям, поскольку все они имеют одинаковый размер и связаны индексом. Есть ли другой элемент управления, который лучше соответствовал бы моим потребностям? я должен также отметить, что я планирую реализовать
TwoWay
привязку для этих свойств