gpt4 book ai didi

c# - 使用 ViewModel (MVVM) 在当前 View 的子用户控件中设置属性

转载 作者:行者123 更新时间:2023-12-03 10:28:44 26 4
gpt4 key购买 nike

我有一个名为 MainContentView.xaml 的主视图我将 DataContext 设置为一个名为 MainContentViewModel.cs 的 ViewModel .在这里,我可以更新 UI 中显示的值,就像普通的 MVVM 一样。
它看起来像这样:

<UserControl x:Class="namespace:MyProject.View.Home.MainContentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UserTools="clr-namespace:MyProject.View.Tools"
xmlns:ViewModel="clr-namespace:MyProject.ViewModel.Home"
mc:Ignorable="d" >
<UserControl.DataContext>
<ViewModel:MainContentViewModel />
</UserControl.DataContext>

<Grid x:Name="mainGrid">
<!-- Normal objects -->
<StackPanel>
<Label Text="Im a label" />
<TextBox />
</StackPanel>
<!-- My Custom Object -->
<UserTools:MyCustomUserControl x:Name="myUserControl" />
</Grid>
</UserControl>

还有我的 MainContentViewModel.cs看起来像这样:
public class MainContentViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;

private string myLabel = "";
public string MyLabel {
get { return this.myLabel; }
set {
this.myLabel = value;
OnPropertyChangedEvent("MyLabel");
}
}

public MainContentViewModel() {
MyLabel = string.Format("my label text");
}

protected virtual void OnPropertyChangedEvent(string _propertyName) {
var _handler = this.PropertyChanged;
if(_handler != null) { _handler(this, new PropertyChangedEventArgs(_propertyName)); }
}
}

现在我想在 MyCustomUserControl.xaml 中设置一些属性通过它自己的 MyCustomUserControlViewModel.cs .
我的 MyCustomUserControl.xaml看起来像这样:
<UserControl x:Class="MyProject.View.Tools.MyCustomUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModel="clr-namespace:MyProject.ViewModel.Tools"
mc:Ignorable="d" >
<UserControl.DataContext>
<ViewModel:MyCustomUserControlViewModel />
</UserControl.DataContext>
<Grid x:Name="mainGrid">
<Label Content="{Binding myCustomLabel}" />
</Grid>
</UserControl>

还有我的 MyCustomUserControlViewModel.cs看起来像这样:
public class MyCustomUserControlViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;

private string myCustomLabel = "";
public string MyCustomLabel {
get { return this.myCustomLabel; }
set {
this.myCustomLabel = value;
OnPropertyChangedEvent("MyCustomLabel");
}
}

public MyCustomUserControlViewModel() {
MyCustomLabel = string.Format("my custom label text");
}

protected virtual void OnPropertyChangedEvent(string _propertyName) {
var _handler = this.PropertyChanged;
if(_handler != null) { _handler(this, new PropertyChangedEventArgs(_propertyName)); }
}
}

现在我想,从 MainContentViewModel.cs ,更新 MyCustomLabel MyUserCustomUserControl.xaml 上的属性(property), 我想我必须通过 MyCustomUserControlViewModel.cs所以我可以保持 MVVM 模式。

我试过这样的事情:
MainContentViewModel.cs
private MyCustomUserControlViewModel _viewModel = new MyCustomUserControlViewModel ();
(...)
public MainContentViewModel() {
(...)
_viewModel.SetMyCustomLabel("my new custom label text");
}

MyCustomUserControlViewModel.cs
public void SetMyCustomLabel(string _text) {
MyCustomLabel = _text;
}

但这不起作用。我猜这是因为我正在实例化另一个 MyCustomUserControlViewModel.cs目的。

那么,我该怎么做呢?

更新和工作 (谢谢谢里登)
我选择了 Sheridan 的一个解决方案,最终得到了这个可行的解决方案。在我的 MainContentView.xaml :
(...)
<UserTools:MyCustomUserControl DataContext="{Binding ChildViewModel, Mode=OneWay}" />

在我的 MainContentViewModel.cs :
private MyCustomUserControlViewModel childViewModel = new MyCustomUserControlViewModel();
public MyCustomUserControlViewModel ChildViewModel {
get { return childViewModel; }
private set { childViewModel = value; OnPropertyChangedEvent("ChildViewModel"); }
}

然后我可以这样做:
public MainContentViewModel() {
(...)
ChildViewModel.SetMyCustomLabel("my new custom label text");
}

最佳答案

如果您的父 View 模型可以访问使用的实际 subview 模型实例(它可能不是因为您实例化 subview 模型的方式),那么您可以简单地这样做:

public MainContentViewModel() {
(...)
_viewModel.CustomLabel = "my new custom label text";
}

1.

一种解决方案是将 subview 模型从 subview 移除到父 View 模型,然后使用 ContentControl 显示 subview 。和 DataTemplate :
<DataTemplate DataType="{x:Type ViewModels:MyCustomUserControlViewModel}">
<Views:MyCustomUserControlView />
</DataTemplate>

...

在 MainContentViewModel 中:
public MyCustomUserControlViewModel ChildViewModel
{
get { return childViewModel; }
private set { childViewModel = value; NotifyPropertyChanged("ChildViewModel"); }
}

...

<Grid x:Name="mainGrid">
<!-- Normal objects -->
<StackPanel>
<Label Text="Im a label" />
<TextBox />
</StackPanel>
<!-- My Custom Object -->
<ContentControl x:Name="myUserControl" Content="{Binding ChildViewModel}" />
</Grid>

这样做可以让您简单地调用该属性,如我的第一个示例所示。

2.

一种替代方法是将属性移动到父 View 模型并直接从 subview 模型绑定(bind)到它 UserControl :
<Grid x:Name="mainGrid">
<Label Content="{Binding DataContext.myCustomLabel, RelativeSource={RelativeSource
AncestorType={x:Type Views:MainContentView}}}" />
</Grid>

更新>>>

3.

好的,我刚刚有了另一个想法……您可以将另一个属性添加到父 View 模型中,并将数据绑定(bind)到 subview 模型,如下所示:
<UserTools:MyCustomUserControl DataContext="{Binding ChildViewModel, 
Mode=OneWayToSource}" x:Name="myUserControl" />

这只是一个猜测,但它可能能够像这样连接到 subview 模型......然后你可以在父 View 模型中执行此操作:
if (ChildViewModel != null) ChildViewModel.CustomLabel = "my new custom label text";

4.

实际上...我刚刚有了另一个想法。您可以从父 View 模型中的属性绑定(bind)到 UserControl如果您添加 DependencyProperty对它:
<UserTools:MyCustomUserControl CustomLabel="{Binding CustomLabelInParentViewModel}" 
x:Name="myUserControl" />

在这种情况下,您可以简单地从 subview 模型中删除该属性。

关于c# - 使用 ViewModel (MVVM) 在当前 View 的子用户控件中设置属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20522531/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com