gpt4 book ai didi

c# - INotifyPropertyChanged 困惑

转载 作者:太空宇宙 更新时间:2023-11-03 23:21:44 24 4
gpt4 key购买 nike

我正在将 VB.NET 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>
</Window>

My MainWindow which is a control window looks like this
```xaml
<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>
</Window>

如果我在控制窗口文本框中键入内容,它会出现在文本 block 的显示窗口中,因此我的绑定(bind)正在工作,并且我可以看到引发了 INotifyPropertyChanged.PropertyChanged 事件。这一切都很好。

但是,如果我以编程方式更改属性,我仍然可以看到引发了 INotifyPropertyChanged.PropertyChanged 事件,但是文本框和文本 block 不会更新为新值。

SheepViewModel.SheepViewModel.GetDetails().CurrentEventName = "This is the new value";

我是不是漏掉了什么?

最佳答案

我真的很惊讶文本更新对你有用;它绝对不在我身边。原因如下:

您在两个窗口中都有以下代码段:

<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>

这基本上是说:创建一个新的 SheepViewModel 实例并将其设置为窗口的数据上下文。因为你在两个窗口中都有它,所以每个窗口都有一个单独的 ViewModel 实例。由于 CurrentEventName 属性是一个实例属性,因此该值不会在实例之间共享,也不会正确更新。

当您尝试以编程方式更新值时,您调用 SheepViewModel.GetDetails()。这会创建另一个实例,与控件使用的实例完全无关。因此,您看不到任何更新。

你想要的是以上所有使用一个 View 模型实例。为此,您可以从后面的代码中设置窗口的 DataContext。您可以在窗口中使用以下构造函数,而不是使用上面的 XAML 代码段:

public DisplayWindow()
{
InitializeComponent();
this.DataContext = SheepViewModel.GetDetails();
}

这确保窗口引用通过 GetDetails 方法检索的单例实例。

关于c# - INotifyPropertyChanged 困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35166810/

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