如何将 MainViewModel 的属性传递给其他 ViewModel,并在 MVVM 应用程序中发生更改时通知它

问题描述 投票:0回答:1

我是编程新手,尤其是 MVVM 框架。我想使用 MVVM 框架制作 WPF 应用程序,但我遇到了将 MainViewModel 的属性 (SupportPath) 的值传递给其他 ViewModel 并在更改时发出通知的问题。

这是我想做的一个例子:

这是我的主窗口,顶部有一个 TextBox,其中包含我想要传递给其他 ViewModel 的 MainViewModel 的 SupoprtPath 属性(字符串)。

主窗口.xaml

<Window x:Class="MVVM_SwitchingViews.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MVVM_SwitchingViews"
        xmlns:models="clr-namespace:MVVM_SwitchingViews.Models"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Row="0" Grid.ColumnSpan="2">
            <StackPanel Orientation="Horizontal">
                <Label Content="Foldername:"/>
                <TextBox Width="600" Margin="3" Text="{Binding SupportPath,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
        </Grid>

        <ContentControl Grid.Row="1" Grid.Column="1" Background="Red" Content="{Binding SelectedViewModel}"/>

        <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Center">
            <Button Margin="10" Width="200" Content="Protokoll" Command="{Binding UpdateViewCommand}" CommandParameter="Protokoll"/>
            <Button Margin="10" Width="200" Content="MillProtokoll" Command="{Binding UpdateViewCommand}" CommandParameter="MillProtokoll"/>
        </StackPanel>
    </Grid>


</Window>

MainViewModel.cs

 public class MainViewModel : BaseViewModel
 {
     private SupportPathModel _supportPathModel;
     public SupportPathModel SupportPathModel
     {
         get { return _supportPathModel; }
         set
         {

             _supportPathModel = value;
             OnPropertyChanged(nameof(SupportPathModel));
         }
     }

     private string _supportPath;
     public string SupportPath
     {
         get { return _supportPathModel.SupportPath; }
         set
         {
             if (string.Equals(value, _supportPathModel.SupportPath, StringComparison.CurrentCulture))
             {
                 return;
             }
             _supportPathModel.SupportPath = value;
             OnPropertyChanged(nameof(SupportPath));
         }
     }

     private BaseViewModel _selectedViewModel;
     public BaseViewModel SelectedViewModel
     {
         get { return _selectedViewModel; }
         set
         {
             _selectedViewModel = value;
             OnPropertyChanged(nameof(SelectedViewModel));
         }
     }

     public ICommand UpdateViewCommand { get; set; }

     public MainViewModel(SupportPathModel supportPathModel)
     {
         _supportPathModel = supportPathModel;
         UpdateViewCommand = new UpdateViewCommand(this);
     }
 }

ProtokollViewModel.cs

public class ProtokollViewModel : BaseViewModel
{
  
    private string _protokollPath;
    public string ProtokollPath
    {
        get { return _protokollPath; }
        set
        {
            _protokollPath = value;
            OnPropertyChanged(nameof(ProtokollPath));
        }
    }

    public ProtokollViewModel()
    {
             

    }

   
}

我读过可以通过使用 Messengeror 的 MVVM Light 或使用事件聚合器的 Prism 来完成,但对我来说很难使用它们。可以使用 Action 来完成并调用它吗?

这是我的意思的一个例子:

SupportPathModel.cs

 public class SupportPathModel : BaseViewModel
 {
     public Action<string> OnSupportChanged;

     private string _supportPath;
     public string SupportPath
     {
         get { return _supportPath; }
         set
         {
             _supportPath = value;
             OnPropertyChanged(nameof(SupportPath));
             OnSupportChanged?.Invoke(_supportPath);
         }
     }



 }

然后在 ProtokollViewModel 中订阅该 Action 并在触发时引发它。我

有人可以帮助我如何实现这一目标吗?

谢谢您的问候

我在类 SupportPathModel.cs 中放置了一个 Action,但我可以从 ProtokollViewModel 调用它

c# wpf mvvm
1个回答
0
投票

在依赖注入中注册ViewModels和Views。在启动应用程序时,您可以设置 DataContext。之后,如果方法或属性是公共的,您可以轻松访问单个 ViewModel。

看起来像这样:

builder.Services.AddSingleton<MyViewModel>();
builder.Services.AddSingleton<View>();


private readonly MyViewModel _viewModel;
private readonly View _view;
private 
public void MainViewModel(MyViewModel viewModel, View view) 
{
    _viewModel = viewModel;
    _view = view;
}
public void OnSetTextOnMyViewModel(string text) 
{
    //Use the Propertie of the other ViewModel which is registered.
    _viewModel.TextBlockValue = "...";
    //You also can create on 'MyViewModel' a method to set the Text and
    //invoke the OnPropertyChanged event to notify that something has 
    //changed.
    _viewModel.SetText("...");
}

//method on MyViewModel
public void SetText(string value) 
{
   //TextBlock Value is binded on .xaml in View
   TextBlockValue = "...";
   OnPropertyChanged(nameof(TextBlockValue));
}

//OnPropertyChanged Method
public class BaseViewModel : INotifyPropertyChanged
{
    public virtual void OnPropertyChanged([CallerMemberName] string 
    propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
//if you want to set it if the value has changed to this:
//this is the property
public string Value 
{
    get => _value;
    set 
       {
           _value = value;
           _viewModel.TextBlockValue = value;
           OnPropertyChanged();
       }
}

也许这会有所帮助。

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.