none
WPF MVVM Entity Framework - привязка данных к ComboBox RRS feed

  • Вопрос

  • Привет!

    Есть таблицы в БД 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>

    Так все работает. 

    9 декабря 2016 г. 19:57

Все ответы

  • Добрый день.

    Я вроде же вам отвечал в соседнем топике, что ElementName=MainWindow не работает, если не задать у элемента доступ к которому вы хотите получить x:Name. Это раз. Два, имя MainWindow  задавать нельзя, т.к. оно совпадает с именем класса.
    Поправьте и посмотрите заработает или нет.

    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>

    Так все работает. 

    9 декабря 2016 г. 19:57