View 不会随着 viewModel 的变化而更新
View does not update with changing viewModel
我有一个名为 SensorControl
的用户控件,我想将其 dataContext 绑定到一个名为 SensorModel
的视图模型 class。
绑定成功,viewModel的初始值在userControl中可见,但问题是当我改变viewModel的属性时,userControl 不更新,我必须手动更新它(通过将 null 分配给它的 dataContext 并再次分配 viewModel)。
这是我的代码的一个简化示例。
SensorControl.xml:
<UserControl ...[other attributes]... DataContext={Binding Model}>
.
.
.
<Label Content="{Binding Title}"/>
.
.
.
</UserControl>
SensorControl.xml.cs(代码隐藏):
public partial class SensorControl : UserControl
{
public SensorModel model;
public SensorModel Model
{
get { return model; }
set { model = value; }
}
public SensorControl(SensorModel sm)
{
Model = sm;
}
}
MainWindow.xml.cs:
public partial class MainWindow : Window
{
public SensorModel sensorModel_1;
public SensorControl sensorControl_1;
public MainWindow()
{
InitializeComponent();
sensorModel_1 = new SensorModel(...[some arguments]...);
sensorControl_1 = new SensorControl(sensorModel_1);
mainGrid.Children.Add(sensorControl_1);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
sensorModel_1.Title = "myTitle";
//The UserControl does not update
}
0) 我在 SensorModel
中实现了 INotifyPropertyChanged
1) 我需要这个的原因是我的项目中只有一个 'Sensor' 的概念(它是一个真正的电子传感器),因此我有一个单一的模型(那个交易使用真实传感器、数据库等),但在 UI 中,我有多个用户控件用于呈现传感器的不同方面。所以我必须为每个真实传感器创建一个模型实例 (SensorModel),并且多个 userControls 必须绑定到它(每个都使用模型的不同部分)。
2) 我不是 WPF 的新手,但我是 MVVM 的新手,我可能误解了一些重要的东西,所以如果有人能清楚地解释正确的方法,我将不胜感激。
提前致谢
在您的用户控件中,删除 DataContext 属性并添加一个 x:Name 属性。然后在您的标签中,像这样绑定:
<UserControl x:Name="uc">
<Label Content="{Binding ElementName=uc,Path=Model.Title}" />
</UserControl>
我认为问题是无法将 DataContext 设置为模型,因为绑定会在父级的 DataContext 中起作用,当它作为子级添加到其中时,父级的 DataContext 将基于 mainGrid。由于 属性 "Model" 在 maiGrid 的 DataContext 中不存在,因此不会发生绑定,因此您的更新不会反映出来。正确获取 UserControl 的 DataContext 可能很棘手。我经常使用 ElementName 或在 UserControl 上创建 DependencyProperties,然后从将使用该控件的父级设置它们。
您需要在您的视图中将 DataContext
设置为您的 ViewModel class,如果您应用 MVVM 模式,您应该使用 ICommand 进行操作。如果你实现一个 MainView class 在后台而不是在 MainWindow class.
中执行逻辑,也许会更好
public MainWindow()
{
InitializeComponent();
DataContext = new MainView();
// sensorModel_1 = new SensorModel(...[some arguments]...);
// sensorControl_1 = new SensorControl(sensorModel_1);
// mainGrid.Children.Add(sensorControl_1);
}
您的主视图 class :
public class MainView {
public SensorControl Control {get; internal set;}
...
}
并在您的 xaml 中更改绑定:
<Label Content="{Binding Control.Model.Title}"/>
感谢大家,我听取了你们的建议,终于找到了方法。
1) 我在 SensorModel
中实现了一个事件,每次任何属性更改时都会触发该事件(名称 ModelChanged
)
2) 然后正如 Merve 和 manOvision 都建议的那样,我在 SensorControl
(SensorModel
类型)中声明了一个依赖项 属性 并将 ui 元素绑定到那个(Binding Path=Model.Title
)
3) 然后我在 SensorControl
中使用此依赖项 属性 的 ModelChanged
事件并引发一个事件(类型为 INotifyPropertyChanged),以便绑定更新它们的值
它工作正常。
我有一个名为 SensorControl
的用户控件,我想将其 dataContext 绑定到一个名为 SensorModel
的视图模型 class。
绑定成功,viewModel的初始值在userControl中可见,但问题是当我改变viewModel的属性时,userControl 不更新,我必须手动更新它(通过将 null 分配给它的 dataContext 并再次分配 viewModel)。
这是我的代码的一个简化示例。
SensorControl.xml:
<UserControl ...[other attributes]... DataContext={Binding Model}>
.
.
.
<Label Content="{Binding Title}"/>
.
.
.
</UserControl>
SensorControl.xml.cs(代码隐藏):
public partial class SensorControl : UserControl
{
public SensorModel model;
public SensorModel Model
{
get { return model; }
set { model = value; }
}
public SensorControl(SensorModel sm)
{
Model = sm;
}
}
MainWindow.xml.cs:
public partial class MainWindow : Window
{
public SensorModel sensorModel_1;
public SensorControl sensorControl_1;
public MainWindow()
{
InitializeComponent();
sensorModel_1 = new SensorModel(...[some arguments]...);
sensorControl_1 = new SensorControl(sensorModel_1);
mainGrid.Children.Add(sensorControl_1);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
sensorModel_1.Title = "myTitle";
//The UserControl does not update
}
0) 我在 SensorModel
INotifyPropertyChanged
1) 我需要这个的原因是我的项目中只有一个 'Sensor' 的概念(它是一个真正的电子传感器),因此我有一个单一的模型(那个交易使用真实传感器、数据库等),但在 UI 中,我有多个用户控件用于呈现传感器的不同方面。所以我必须为每个真实传感器创建一个模型实例 (SensorModel),并且多个 userControls 必须绑定到它(每个都使用模型的不同部分)。
2) 我不是 WPF 的新手,但我是 MVVM 的新手,我可能误解了一些重要的东西,所以如果有人能清楚地解释正确的方法,我将不胜感激。
提前致谢
在您的用户控件中,删除 DataContext 属性并添加一个 x:Name 属性。然后在您的标签中,像这样绑定:
<UserControl x:Name="uc">
<Label Content="{Binding ElementName=uc,Path=Model.Title}" />
</UserControl>
我认为问题是无法将 DataContext 设置为模型,因为绑定会在父级的 DataContext 中起作用,当它作为子级添加到其中时,父级的 DataContext 将基于 mainGrid。由于 属性 "Model" 在 maiGrid 的 DataContext 中不存在,因此不会发生绑定,因此您的更新不会反映出来。正确获取 UserControl 的 DataContext 可能很棘手。我经常使用 ElementName 或在 UserControl 上创建 DependencyProperties,然后从将使用该控件的父级设置它们。
您需要在您的视图中将 DataContext
设置为您的 ViewModel class,如果您应用 MVVM 模式,您应该使用 ICommand 进行操作。如果你实现一个 MainView class 在后台而不是在 MainWindow class.
public MainWindow()
{
InitializeComponent();
DataContext = new MainView();
// sensorModel_1 = new SensorModel(...[some arguments]...);
// sensorControl_1 = new SensorControl(sensorModel_1);
// mainGrid.Children.Add(sensorControl_1);
}
您的主视图 class :
public class MainView {
public SensorControl Control {get; internal set;}
...
}
并在您的 xaml 中更改绑定:
<Label Content="{Binding Control.Model.Title}"/>
感谢大家,我听取了你们的建议,终于找到了方法。
1) 我在 SensorModel
中实现了一个事件,每次任何属性更改时都会触发该事件(名称 ModelChanged
)
2) 然后正如 Merve 和 manOvision 都建议的那样,我在 SensorControl
(SensorModel
类型)中声明了一个依赖项 属性 并将 ui 元素绑定到那个(Binding Path=Model.Title
)
3) 然后我在 SensorControl
中使用此依赖项 属性 的 ModelChanged
事件并引发一个事件(类型为 INotifyPropertyChanged),以便绑定更新它们的值
它工作正常。