我是编程新手,尤其是 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 调用它
在依赖注入中注册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();
}
}
也许这会有所帮助。
祝你好运!