Получить уведомление PropertyChanged от одной ViewModel к другой - PullRequest
0 голосов
/ 08 января 2020

Я работаю над своим первым проектом WPF. Мой интерфейс должен быть более интерактивным. У меня есть 2 ViewModels. MainWindowViewModel и WorldViewModel.

Упрощенный код MainWindow xaml:

<Window>
    [...]
    <Window.DataContext>
        <vm:MainWindowViewModel />
    </Window.DataContext>

    <Grid>
        <!--Worlds combobox-->
        <ComboBox Margin="2 0 0 0" MinWidth="100" IsEnabled="{Binding IsWorldsComboEnabled}"
        ItemsSource="{Binding WorldViewModel.Worlds}" SelectedValue="{Binding WorldViewModel.CurrentWorld}"
        DisplayMemberPath="Name"/>
    </Grid>
</Window>

Код MainWindowViewModel.cs:

public class MainWindowViewModel : BaseViewModel
{
    public WorldViewModel WorldViewModel { get; set; }

    public bool IsWorldsComboEnabled => WorldViewModel.Worlds != null;

    /// <summary>
    /// Default constructor
    /// </summary>
    public MainWindowViewModel()
    {
        WorldViewModel = WorldViewModel.Instance;
    }
}

Код WorldViewModel.cs:

public class WorldViewModel : BaseViewModel
{
    public ObservableCollection<World> Worlds { get; set; }

    public World CurrentWorld { get; set; }

    public static WorldViewModel Instance { get; set; }

    // Called on startup
    public static void Initialize()
    {
        Instance = new WorldViewModel();
    }

    /// <summary>
    /// Default constructor
    /// </summary>
    public WorldViewModel()
    {

    }
}

ViewModels немного больше, но это минимально необходимый код. BaseViewModel - это класс, который предоставляет интерфейс NotifyPropertyChanged с PropertyChanged.Fody пакетом NuGet.

Мой ComboBox должен быть отключен, когда Worlds ObservableCollection имеет значение null. Он хорошо работает, когда IsWorldsComboEnabled находится в WorldViewModel, но я чувствую, что это не путь к go. Несколько представлений будут зависеть от WorldViewModel, но им не потребуется свойство IsWorldsComboEnabled. Так что это место в MainWindowViewModel.

Есть ли способ уведомить MainWindowViewModel, когда свойство в WorldViewModel изменилось?

1 Ответ

0 голосов
/ 08 января 2020

Проблема со следующей строкой кода состоит в том, что установщик IsWorldsComboEnabled никогда не будет выполнен, даже если WorldViewModel.Worlds изменился, поэтому ваш PropertyChangedEventHandler не будет вызван.

public bool IsWorldsComboEnabled => WorldViewModel.Worlds != null

Вы может измениться на public bool IsWorldsComboEnabled { get; set; } и вычислить следующее выражение

IsWorldsComboEnabled = WorldViewModel.Worlds != null;

при каждом изменении свойства WorldViewModel.Worlds.

В вашем случае, когда свойство имеет значение ObservableCollection, вы можете зарегистрироваться в событии CollectionChanged

WorldViewModel.Worlds.CollectionChanged += MyCollectionChangedMethod;

и оценить там выражение

private void MyCollectionChangedMethod(object sender, NotifyCollectionChangedEventArgs e)
{
  IsWorldsComboEnabled = WorldViewModel.Worlds != null;
}
...