如何在 WPF 中强制重新绑定 WinRT?
How to force a rebind in WinRT as it is possible in WPF?
我有一个基于 Prism 的 WinRT 项目,包含多个页面、用户控件等。
出于某种原因,我需要将多个视图绑定到视图模型访问的单个模型对象(每个视图都属于一个视图)。
单个模型对象像其他对象一样由 Unity 容器注入,需要像事件聚合器一样是单例的。
为了简单起见,我做了一个例子,每个视图中只有一个 bool 变量绑定到一个复选框,它应该在视图上同步。
我的问题是:当我选中主页中的复选框时,第二页中的复选框在导航到该页面时跟随值(示例中的 UserInpuPage),但不是主页上 UserControl 位置中的复选框。
调试会话后,我看到单个模型中的变量具有正确的值,但用户控件(示例中的 MyUserControl)上的 GUI 未更新。
像 GetBindingExpression(...) 和 WPF 中的 UpdateTarget() 这样的机制似乎不存在于 WinRT 库中。
出于设计原因(使用 prism mvvm 我不想破坏 vm 的自动装配和动态实例化的概念)在页面的资源部分定义的静态上下文 and/or usercontrol 不是我正在寻找的对于.
如何使用模型实现用户控件中复选框的更新,就像它在导航后用于 userinputpage 一样?
任何帮助将不胜感激。
// Interface mendatory to work with Unitiy-Injection for RegisterInstance<ISingletonVM>(...)
public interface ISingletonVM
{
bool TestChecked{ get; set; }
}
public class SingletonVM : BindableBase, ISingletonVM
{
bool _testChecked = false;
public bool TestChecked
{
get
{
return _testChecked;
}
set
{
SetProperty(ref _testChecked, value);
}
}
}
这是视图模型中的相关代码(每个虚拟机都相同,但在这种情况下来自用户控件的虚拟机):
class MyUserControlViewModel : ViewModel
{
private readonly ISingletonVM _singletonVM;
public MyUserControlViewModel(ISingletonVM singletonVM)
{
_singletonVM = singletonVM;
}
public bool TestChecked
{
get
{
return _singletonVM.TestChecked;
}
set
{
_singletonVM.TestChecked = value;
}
}
}
三个视图的相关XAML代码片段:
主页:
<prism:VisualStateAwarePage x:Name="pageRoot" x:Class="HelloWorldWithContainer.Views.MainPage"...>
...
<StackPanel Grid.Row="2" Orientation="Horizontal">
<ctrl:MyUserControl ></ctrl:MyUserControl>
<CheckBox IsChecked="{Binding TestChecked, Mode=TwoWay}" Content="CheckBox" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</StackPanel>
...
用户输入页面:
<prism:VisualStateAwarePage x:Name="pageRoot"
x:Class="HelloWorldWithContainer.Views.UserInputPage"
...
<CheckBox IsChecked="{Binding TestChecked, Mode=TwoWay}" Content="CheckBox" HorizontalAlignment="Left" Margin="440,190,0,0" VerticalAlignment="Top"/>
...
用户控件:
<UserControl
x:Class="HelloWorldWithContainer.Views.MyUserControl" prism:ViewModelLocator.AutoWireViewModel="True"
<Grid>
<CheckBox Content="CheckBox" IsChecked="{Binding TestChecked, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="282"/>
</Grid>
您的用户控件永远不会收到有关 MyUserControlViewModel.TestChecked
属性 更改的通知,这就是视图永远不会更新的原因。要解决此问题,您可以做的一件事是在 MyUserControlViewModel
的构造函数中订阅您的 SingletonVM.PropertyChanged
事件。您的 ISingletonVM
需要实现 INotifyPropertyChanged
接口。所以 MyUserControlViewModel
的构造函数将是这样的:
public MyUserControlViewModel(ISingletonVM singletonVM)
{
_singletonVM = singletonVM;
_singletonVM.PropertyChanged += (sender, args) => OnPropertyChanged("TestChecked");
}
我有一个基于 Prism 的 WinRT 项目,包含多个页面、用户控件等。 出于某种原因,我需要将多个视图绑定到视图模型访问的单个模型对象(每个视图都属于一个视图)。 单个模型对象像其他对象一样由 Unity 容器注入,需要像事件聚合器一样是单例的。 为了简单起见,我做了一个例子,每个视图中只有一个 bool 变量绑定到一个复选框,它应该在视图上同步。 我的问题是:当我选中主页中的复选框时,第二页中的复选框在导航到该页面时跟随值(示例中的 UserInpuPage),但不是主页上 UserControl 位置中的复选框。 调试会话后,我看到单个模型中的变量具有正确的值,但用户控件(示例中的 MyUserControl)上的 GUI 未更新。 像 GetBindingExpression(...) 和 WPF 中的 UpdateTarget() 这样的机制似乎不存在于 WinRT 库中。 出于设计原因(使用 prism mvvm 我不想破坏 vm 的自动装配和动态实例化的概念)在页面的资源部分定义的静态上下文 and/or usercontrol 不是我正在寻找的对于.
如何使用模型实现用户控件中复选框的更新,就像它在导航后用于 userinputpage 一样? 任何帮助将不胜感激。
// Interface mendatory to work with Unitiy-Injection for RegisterInstance<ISingletonVM>(...)
public interface ISingletonVM
{
bool TestChecked{ get; set; }
}
public class SingletonVM : BindableBase, ISingletonVM
{
bool _testChecked = false;
public bool TestChecked
{
get
{
return _testChecked;
}
set
{
SetProperty(ref _testChecked, value);
}
}
}
这是视图模型中的相关代码(每个虚拟机都相同,但在这种情况下来自用户控件的虚拟机):
class MyUserControlViewModel : ViewModel
{
private readonly ISingletonVM _singletonVM;
public MyUserControlViewModel(ISingletonVM singletonVM)
{
_singletonVM = singletonVM;
}
public bool TestChecked
{
get
{
return _singletonVM.TestChecked;
}
set
{
_singletonVM.TestChecked = value;
}
}
}
三个视图的相关XAML代码片段:
主页:
<prism:VisualStateAwarePage x:Name="pageRoot" x:Class="HelloWorldWithContainer.Views.MainPage"...>
...
<StackPanel Grid.Row="2" Orientation="Horizontal">
<ctrl:MyUserControl ></ctrl:MyUserControl>
<CheckBox IsChecked="{Binding TestChecked, Mode=TwoWay}" Content="CheckBox" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</StackPanel>
...
用户输入页面:
<prism:VisualStateAwarePage x:Name="pageRoot"
x:Class="HelloWorldWithContainer.Views.UserInputPage"
...
<CheckBox IsChecked="{Binding TestChecked, Mode=TwoWay}" Content="CheckBox" HorizontalAlignment="Left" Margin="440,190,0,0" VerticalAlignment="Top"/>
...
用户控件:
<UserControl
x:Class="HelloWorldWithContainer.Views.MyUserControl" prism:ViewModelLocator.AutoWireViewModel="True"
<Grid>
<CheckBox Content="CheckBox" IsChecked="{Binding TestChecked, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="282"/>
</Grid>
您的用户控件永远不会收到有关 MyUserControlViewModel.TestChecked
属性 更改的通知,这就是视图永远不会更新的原因。要解决此问题,您可以做的一件事是在 MyUserControlViewModel
的构造函数中订阅您的 SingletonVM.PropertyChanged
事件。您的 ISingletonVM
需要实现 INotifyPropertyChanged
接口。所以 MyUserControlViewModel
的构造函数将是这样的:
public MyUserControlViewModel(ISingletonVM singletonVM)
{
_singletonVM = singletonVM;
_singletonVM.PropertyChanged += (sender, args) => OnPropertyChanged("TestChecked");
}