Лучший отвечающий
WPF MVVM Entity Framework - привязка данных к ComboBox

Вопрос
-
Привет!
Есть таблицы в БД MS SQL (таблица Поручение и таблица Состояние):
Написана ViewModel:
class ErrandViewModel : ViewModelBase { // Конструктор класса public ErrandViewModel() { dbContext = new ErrandContext(); GetErrands(); } #region Переменные ErrandContext dbContext; private List<Errand> _errands; private List<State> _states; private Errand _selectedErrand; private State _selectedState; #endregion #region Свойства public List<Errand> Errands { get { return _errands; } set { _errands = value; NotifyPropertyChanged(); } } public List<State> States { get { return _states; } set { _states = value; NotifyPropertyChanged(); } } public Errand SelectedErrand { get { return _selectedErrand; } set { _selectedErrand = value; NotifyPropertyChanged(); } } public State SelectedState { get { return _selectedState; } set { _selectedState = value; NotifyPropertyChanged(); } } #endregion #region Методы private void GetErrands() { var query = dbContext.Errand.ToList(); this.Errands = query; } #endregion } // Конец class
Объявление ViewModel и привязка к контексту данных:
public partial class MainWindow : Window { private ErrandViewModel viewModel = new ErrandViewModel(); public MainWindow() { InitializeComponent(); this.DataContext = viewModel; } }
Есть DataGrid, который отображает статус в виде текста:
<DataGrid x:Name="dataGrid" Margin="10,10,10,200" AutoGenerateColumns="False" CanUserAddRows="True" SelectionMode="Single" ItemsSource="{Binding Errands}" SelectedItem="{Binding SelectedErrand, Mode=TwoWay}"> <DataGrid.Columns> <DataGridTextColumn Header="Номер" Width="75" Binding="{Binding Number, Mode=TwoWay}"/> <DataGridTextColumn Header="Состояние" Binding="{Binding State.Name, Mode=TwoWay}"/> </DataGrid.Columns> </DataGrid>
Пытался статус переделать на DataGridComboBox, но не получается. Потуги примерно такие:
<DataGridComboBoxColumn Header="Состояние" DisplayMemberPath="Name" SelectedValuePath="State.Name" SelectedValueBinding="{Binding StateId}"> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="{x:Type ComboBox}"> <Setter Property="ItemsSource" Value="{Binding ElementName=MainWindow, Path=DataContext.States, Mode=TwoWay}"/> </Style> </DataGridComboBoxColumn.ElementStyle> </DataGridComboBoxColumn>
Код выше нерабочий, ничего не отображается в комбобоксе.
DisplayMemberPath="Name"
Понятно, значение свойства (Либо id либо Name), которое будет отображаться в строке.
SelectedValuePath="State.Name"
По сути это поле объекта. Т.е. Должно быть Name
SelectedValueBinding="{Binding StateId}">
Возвращаем id для выбранного Name (наверно, это так трактуется)
Дальше нашел приблизительный пример привязки на StackOverFlow, но это не помогло.
Помогите разобраться в чем проблема :)
5 декабря 2016 г. 12:38
Ответы
-
Временно сделал немного по другому, пока не прояснится с первым вариантом привязки.
Решение нашел на Тостер и адаптировал под себя:
<DataGridComboBoxColumn Header="Состояние" DisplayMemberPath="Name" SelectedValueBinding="{Binding State}" SelectedValuePath="{Binding id}"> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="{x:Type ComboBox}"> <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.States, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </Style> </DataGridComboBoxColumn.ElementStyle> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="{x:Type ComboBox}"> <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.States, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </Style> </DataGridComboBoxColumn.EditingElementStyle> </DataGridComboBoxColumn>
Так все работает.
- Помечено в качестве ответа Maksim MarinovMicrosoft contingent staff, Moderator 27 декабря 2016 г. 8:41
9 декабря 2016 г. 19:57
Все ответы
-
Добрый день.
Я вроде же вам отвечал в соседнем топике, что ElementName=MainWindow не работает, если не задать у элемента доступ к которому вы хотите получить x:Name. Это раз. Два, имя MainWindow задавать нельзя, т.к. оно совпадает с именем класса.
Поправьте и посмотрите заработает или нет.- Предложено в качестве ответа Maksim MarinovMicrosoft contingent staff, Moderator 6 декабря 2016 г. 8:25
6 декабря 2016 г. 7:28Отвечающий -
Извиняюсь, что долго не отвечал. Задал для окна x:Name = MyWindow, изменил ElementName=MyWindow, но нет - изменений никаких не произошло. Видимо проблема еще в чем-то.9 декабря 2016 г. 18:14
-
Временно сделал немного по другому, пока не прояснится с первым вариантом привязки.
Решение нашел на Тостер и адаптировал под себя:
<DataGridComboBoxColumn Header="Состояние" DisplayMemberPath="Name" SelectedValueBinding="{Binding State}" SelectedValuePath="{Binding id}"> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="{x:Type ComboBox}"> <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.States, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </Style> </DataGridComboBoxColumn.ElementStyle> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="{x:Type ComboBox}"> <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.States, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </Style> </DataGridComboBoxColumn.EditingElementStyle> </DataGridComboBoxColumn>
Так все работает.
- Помечено в качестве ответа Maksim MarinovMicrosoft contingent staff, Moderator 27 декабря 2016 г. 8:41
9 декабря 2016 г. 19:57