我正在将VBnet winforms项目转换为C#WPF。两者都是新的,所以试图弄明白。
我有一个项目有两个WPF窗口和一个ViewModel作为引用项目。
public class SheepViewModel : INotifyPropertyChanged
{
private string _CurrentEventName;
public string CurrentEventName
{
get { return _CurrentEventName; }
set
{
_CurrentEventName = value;
OnPropertyChanged("CurrentEventName");
}
}
static SheepViewModel _details;
public static SheepViewModel GetDetails()
{
if (_details == null)
_details = new SheepViewModel();
return _details;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
Console.WriteLine(prop + " has changed");
}
}
我显示事物的窗口看起来像这样。
<Window
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:vm="clr-namespace:SheepViewModel;assembly=SheepViewModel"
xmlns:ShaderEffectLibrary="clr-namespace:ShaderEffectLibrary;assembly=ShaderEffectLibrary" x:Class="Sheep_Score_3._1.ScoreScreen"
mc:Ignorable="d"
Title="ScoreScreen" Height="540" Width="920" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
<Viewbox x:Name="Stand1ViewBox" RenderTransformOrigin="0.5,0.5">
<Canvas x:Name="StandViewBox" Height="112.513" Margin="0,1100,2,0" VerticalAlignment="Bottom" RenderTransformOrigin="0.493,0.473" Background="#FF999999" Width="2268">
<TextBlock x:Name="CurrentEventName" Canvas.Left="270.9" TextWrapping="Wrap" Width="1104.815" FontFamily="Calibri" FontSize="29.333" FontStyle="Italic" Canvas.Top="-1.649" Text="{Binding Path=CurrentEventName}"/>
</Canvas>
</Viewbox>
我的MainWindow是一个控制窗口,如下所示
<Window x:Class="Sheep_Score_3._1.MainWindow"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
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:vm="clr-namespace:SheepViewModel;assembly=SheepViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="433.689" Width="941.194">
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
<Grid Margin="0,0,0,0">
<TextBox x:Name="CurrentEventName" Height="23" Margin="131.01,163.013,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left" Width="327.151" Text="{Binding CurrentEventName, Mode=TwoWay}"/>
</Grid>
现在,如果我在控制窗口文本框中输入内容,它会出现在文本块的“显示”窗口中,因此我的绑定正在运行,我可以看到NotifyProperyChange消息。这一切都很有效。
但是,如果我以编程方式更改属性,我仍然可以看到NotifyPropertyChange触发,但文本框和文本块不会使用新值更新。
SheepViewModel.SheepViewModel.GetDetails().CurrentEventName = "This is the new value";
我在这里遗漏了什么吗? 任何有关这方面的指导都会受到欢迎,我已经检查过我正在调用正确的地产名称并用Google搜索这几天,试图找出它,但我现在完全被卡住了。
答案 0 :(得分:2)
我真的很惊讶文本更新对你有用;它肯定不在我身边。这就是原因:
两个窗口中都有以下代码段:
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
这基本上说:创建一个SheepViewModel的新实例并将其设置为窗口的datacontext。由于在两个窗口中都有这个,因此每个窗口都有一个单独的ViewModel实例。由于CurrentEventName
属性是一个实例属性,因此不会在实例之间共享该值,并且无法正确更新。
当您尝试以编程方式更新该值时,请致电SheepViewModel.GetDetails()
。这创建了另一个实例,与控件使用的实例完全无关。因此,您没有看到任何更新。
你想要的就是使用一个单一的viewmodel实例。为此,您可以从后面的代码设置窗口的DataContext。您可以在Windows中使用以下构造函数,而不是使用上面的XAML代码段:
public DisplayWindow()
{
InitializeComponent();
this.DataContext = SheepViewModel.GetDetails();
}
这可确保窗口引用通过GetDetails
方法检索的单例实例。
答案 1 :(得分:1)
为了保证您的Windows共享相同的视图模型,请删除Steven记下的片段,并在Windows的构造函数中调用以下内容:
DataContext = SheepViewModel.GetDetails();