Как связать DataGridComboBoxColumn с EntityFramework, используя MVVM? - PullRequest
0 голосов
/ 17 февраля 2012

Я пытаюсь заставить DataGridComboBoxColumn работать с моей ViewModel.Кажется, все работает правильно, но когда я изменяю значение поля со списком, сущность не изменяется.

Текст данных окна имеет следующие свойства:

ItemsSource

Public Property AllEnergySources() As ObservableCollection(Of EnergySourceViewModel)

SelectedItemBinding

  Private _CurrentEnergySource As EnergySourceViewModel
    Public Property CurrentEnergySource() As EnergySourceViewModel
        Get
            Return _CurrentEnergySource
        End Get
        Set(ByVal value As EnergySourceViewModel)
            _CurrentEnergySource = value
            OnPropertyChanged("CurrentEnergySource")
        End Set
    End Property

Я чувствую, что проблема заключается в том, как я заполняю CurrentEnergySource в ViewModel, который является DataContext:

Sub New(SelectedEntity as EquipmentEnergySource)
     AllEnergySources = New ObservableCollection(Of EnergySourceViewModel)

    //Select all EnergySources from the EntityFramework
     Dim EnergyEntities = From esr in db.EnergySources Select esr

                //Loop through to convert Entity POCO to Collection of ViewModels
                For Each es In EnergyEntities
                    _AllEnergySources.Add(New EnergySourceViewModel(es))

                    //Optionally Set the newly created ViewModel to SelectedItemBinding object
                    If es.EnergySourceID = SelectedEntity.EnergySourceID Then
                        _CurrentEnergySource = _AllEnergySources.Last
                    End If
                Next
End Sub

Когда я создаю резервную базу для комбинированного списка, если модель выбрана, я устанавливаюэта модель представления является CurrentEnergySource, но после этого она отключается (и в этом проблема)

На что следует ссылаться в CurrentEnergySource, чтобы он обновлял модель при изменении поля со списком?

Ответы [ 4 ]

1 голос
/ 21 февраля 2012

Одна вещь, которая кажется неправильной, это то, что вы, вероятно, должны использовать SelectedValueBinding, а не SelectedItemBinding.

Вот пример, который мне подходит:

<Page.Resources>
    <ViewModel:DataGridComboBoxViewModel x:Key="model"/>
    <Style x:Key="ElementStyle" TargetType="ComboBox">
        <Setter 
            Property="ItemsControl.ItemsSource" 
            Value="{Binding Path=DataContext.DetailItems, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
            />
    </Style>
</Page.Resources>

<Grid DataContext="{StaticResource model}">
    <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridComboBoxColumn Header="Combo" 
                                    DisplayMemberPath="Name" 
                                    SelectedValueBinding="{Binding DetailItem}" 
                                    ElementStyle="{StaticResource ElementStyle}"
                                    EditingElementStyle="{StaticResource ElementStyle}"
                                    >
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

public class DataItem : ViewModelBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; } 

    private DetailItem _detailItem;
    public DetailItem DetailItem
    {
        get { return _detailItem; }
        set
        {
            Debug.WriteLine(value != null
                                ? string.Format("Setting detail item to: {0}", value.Name)
                                : "Setting detail item to null.");

            Set(() => DetailItem, ref _detailItem, value);
        }
    }
}

public class DetailItem : ViewModelBase
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class DataGridComboBoxViewModel : ViewModelBase
{
    public DataGridComboBoxViewModel()
    {
        DetailItems = new List<DetailItem>
                          {
                              new DetailItem {Id = 0, Name = "Zero"},
                              new DetailItem {Id = 1, Name = "One"},
                              new DetailItem {Id = 2, Name = "Two"},
                              new DetailItem {Id = 3, Name = "Three"},
                          };

        Items = new List<DataItem>
                    {
                        new DataItem {Id = 0, Name = "Item 1", Description = "This is item 1"},
                        new DataItem {Id = 1, Name = "Item 2", Description = "This is item 2"},
                        new DataItem {Id = 2, Name = "Item 3", Description = "This is item 3"},
                        new DataItem {Id = 3, Name = "Item 4", Description = "This is item 4"},
                    };
    }

    public List<DataItem> Items { get; set; }
    public List<DetailItem> DetailItems { get; private set; }
}
0 голосов
/ 07 марта 2012

Мой ответ: вам нужно изменить внешний ключ вручную (теперь я изменяю его в установщике CurrentEnergySource, который является связанным свойством SelectedItemBinding)

     Private _CurrentEnergySource As EnergySourceViewModel
    Public Property CurrentEnergySource() As EnergySourceViewModel
        Get
            Return _CurrentEnergySource
        End Get
        Set(ByVal value As EnergySourceViewModel)
            _CurrentEnergySource = value
            Me.Model.EnergySourceID = value.Model.EnergySourceID
            OnPropertyChanged("CurrentEnergySource")
        End Set
    End Property

При загрузке вместо свойства укажите заполненное хранилище резервных копий _CurrentEnergySource, чтобы избежать запуска всех объектов с измененным состоянием

0 голосов
/ 24 февраля 2012

Вы пробовали RelativeSource для привязки? обычно я нахожу, когда привязываюсь к столбцу в шаблоне и т. д., привязка выглядит внутри привязки элемента управления, а не привязки к текстовому тексту представления.

Попробуйте либо:

"{Binding Path=DataContext.CurrentEnergySource, 
          RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},
          Mode=TwoWay}"

или

"{Binding ElementName=NameOfTheView, 
          Path=DataContext.CurrentEnergySource, 
          Mode=TwoWay}"

и затем добавление x:Name="NameOfTheView" к атрибутам представления (ниже места xmlns внутри> скобки)

0 голосов
/ 18 февраля 2012

Конечно, проблема в вашей привязке, DataGridComboBoxColumn автоматически берет один элемент из CurrentEnergySource, а у CurrentEnergySource нет AllEnergySources, Whey, который вы не используете отдельно.

            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding SelectedItemFromItemsSource}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding ItemsSource}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...