Настройка FK модели через привязку данных MVVM (из выпадающего списка) - PullRequest
0 голосов
/ 26 декабря 2018

Это мой первый проект WPF MVVM EF, и хотя опыт был очень грубым, и я сомневаюсь, что когда-нибудь вернусь к ним, я намерен закончить его.У меня есть вид, где вы можете редактировать Hardware свойства модели.Он отлично работает для «простых» свойств, таких как строки, целые числа, DateTime и так далее.Но по какой-то причине я не могу заставить его работать с несколькими свойствами FK, которые есть у этой модели.
Вот код view-viewModel-model:

<UserControl x:Class="WPFapp.Views.HardwareManipulationWindowView">
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type localVM:HardwareManipulationViewModel}">
            <local:HardwareManipulationWindowView />
        </DataTemplate>
    </UserControl.Resources>
    <ComboBox SelectedValue="{Binding Hardware.CurrentlyBeingUsedByProgram.GUID, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
              ItemsSource="{Binding ProgramsList}" SelectedValuePath="GUID">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Title}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
</UserControl>

internal class HardwareManipulationViewModel : NotificationObject
{
    public HardwareManipulationViewModel(Hardware hardware, ObservableCollection<Program> programsList)
    {
        Hardware = hardware;
        ProgramsList = programsList;
    }

    public ObservableCollection<Program> ProgramsList { get; set; }

    public Hardware Hardware { get; }

    internal void WriteChangesInto(Hardware selectedItem)
    {
        selectedItem.Type = Hardware.Type;
        selectedItem.Label = Hardware.Label;
        selectedItem.Description = Hardware.Description;
        selectedItem.Remarks = Hardware.Remarks;
        selectedItem.CurrentLocation = Hardware.CurrentLocation;
        selectedItem.CurrentStatus = Hardware.CurrentStatus;
        //all of the above work just fine, but these 2 FKs below don't work at all
        selectedItem.CurrentlyBeingCarriedByPerson = Hardware.CurrentlyBeingCarriedByPerson; 
        selectedItem.CurrentlyBeingUsedByProgram = Hardware.CurrentlyBeingUsedByProgram;
    }
}

public class Hardware : NotificationObject
{
    protected Hardware()
    {
        GUID = Guid.NewGuid();
    }

    Guid _guid;
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Guid GUID { get { return _guid; } private set { _guid = value; OnPropertyChanged(); } }

    string _label;
    public string Label { get { return _label; } set { _label = value; OnPropertyChanged(); } }
    string _description;
    public string Description { get { return _description; } set { _description = value; OnPropertyChanged(); } }
    string _remarks;
    public string Remarks { get { return _remarks; } set { _remarks = value; OnPropertyChanged(); } }

    Program _currentlyBeingUsedByProgram;
    public Program CurrentlyBeingUsedByProgram { get { return _currentlyBeingUsedByProgram; } set { _currentlyBeingUsedByProgram = value; OnPropertyChanged(); } }
}

Я явно пропустил много шумакод.Для всех, кому интересно, NotificationObject - это базовая INotifyPropertyChanged реализация.Теперь все вышеперечисленное обрабатывается внутри этого единственного метода:

private void InvokeEditHardwareDialog()
{
    HardwareManipulationViewModel viewModel = new HardwareManipulationViewModel(SelectedItem.Clone(), new ObservableCollection<Program>(_dbContext.EagerLoad<Program>()));
    var window = WindowService.CreateWindowHostingViewModel(viewModel, true);
    window.ShowDialog();
    if (viewModel.DialogResult.GetValueOrDefault())
    {
        viewModel.WriteChangesInto(SelectedItem);
        _dbContext.Update(SelectedItem);
    }
}

Теперь проблема в том, что когда отладчик переходит в этот метод WriteChangesInto, все реквизиты выше строки комментария, которую я вставилтам есть их новые значения, измененные с помощью представления, но для последних 2 (внешний ключ) свойств ничего не происходит, несмотря на правильную загрузку значений в выпадающем списке.Hardware.CurrentlyBeingUsedByProgram содержит любое значение, с которого оно началось.Что я здесь не так делаю?Насколько мне известно, это должно работать просто отлично.

1 Ответ

0 голосов
/ 29 декабря 2018

Скорее всего, проблема возникает между связью EF и WPF.Я закончил тем, что использовал обходной путь, который включает использование дополнительного свойства для хранения значения FK:

private Program _hardwareProgram;
public Program HardwareProgram { get { return _hardwareProgram; } set { _hardwareProgram = value; OnPropertyChanged(); } }

И XAML:

<ComboBox SelectedValue="{Binding HardwareProgram}"
                          ItemsSource="{Binding ProgramsList}"  IsSynchronizedWithCurrentItem="True">

Затем в вашем ctor вы просто читаете это значение _hardwareProgram = hardware.CurrentlyBeingUsedByProgram; и ты в порядке.

...