我正在尝试使用 ContentControl 和 DataTemplate 在我的代码中切换视图模型。该代码有效,并且似乎正确绑定,但输出中出现错误:
System.Windows.Data Error: 40 : BindingExpression path error: 'Value1' property not found on 'object' ''ViewModel2' (HashCode=1202201)'. BindingExpression:Path=Value1; DataItem='ViewModel2' (HashCode=1202201); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'Value2' property not found on 'object' ''ViewModel1' (HashCode=7634749)'. BindingExpression:Path=Value2; DataItem='ViewModel1' (HashCode=7634749); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
MainView(容器)的代码:
<DataTemplate DataType="{x:Type local:ViewModel1}" >
<local:View1 DataContext="{Binding ElementName=UserControlContainer, Path=Content}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModel2}" >
<local:View2 DataContext="{Binding ElementName=UserControlContainer, Path=Content}"/>
</DataTemplate>
...
<ContentControl x:Name="UserControlContainer" Content="{Binding CurrentViewModel}"/>
MainViewModel.cs 包含:
private ViewModelBase m_viewModel = null;
public ViewModelBase CurrentViewModel
{
get
{
return m_viewModel;
}
set
{
m_viewModel = value;
RaisePropertyChanged("CurrentViewModel");
}
}
private void EventTimer(object sender, EventArgs e)
{
if (CurrentViewModel == null || CurrentViewModel.GetType() == typeof(ViewModel1))
{
CurrentViewModel = new ViewModel2();
}
else
{
CurrentViewModel = new ViewModel1();
}
CommandManager.InvalidateRequerySuggested();
}
ViewModel1 和 ViewModel2 具有相同的代码,只是它们引用了自己的视图模型及其上的属性(ViewModel1 的 Value1 和 ViewModel2 的 Value2):
视图模型1:
public class ViewModel1 : ViewModelBase
{
public double m_value = new Random((int)DateTime.Now.ToBinary()).NextDouble();
public string Value1
{
get { return m_value.ToString(); }
}
}
视图1:
<TextBlock Text="{Binding Value1}"/>
我猜问题是当计时器更改属性 CurrentViewModel 中的 ViewModel 时,未显示的视图仍在内存中并尝试绑定到错误的 ViewModel(因此 View2 尝试从 ViewModel1 获取 Value2)。
有没有办法解决这个问题?因此,仅当 CurrentViewModel 的类型是正确的类型时才会发生绑定。(我可以使用转换器并将预期类型作为参数传递,但是有没有更好的解决方案?)
谢谢!