【问题标题】:WPF C# PropertyChanged always nullWPF C# PropertyChanged 始终为空
【发布时间】:2018-03-13 17:28:15
【问题描述】:

我已经玩了一段时间,并决定看看是否有人可以提供帮助,我在 StatusInfo 的构造函数中设置了 DataContext = this 并且没有工作。当我将字符串写入 ScreenStatusBarText 时,它确实调用了 OnPropertyChanged 方法,但每次 PropertyChanged 值为空。我在屏幕底部的状态块。我在此堆栈面板上方有一个选项卡部分,其中包含许多使用绑定和工作的组件。

屏幕代码

<StackPanel Margin="0,1047,0,0">
  <Grid Name="StatusBarItemGrid">
  <TextBlock Name="StatusBarText" Text="may the force be with you"   VerticalAlignment="Center" HorizontalAlignment="Stretch" />
  </Grid>
 </StackPanel>

数据模型:

public partial class StatusInfo :  INotifyPropertyChanged
{

    private string screenStatusBarText;

    public StatusInfo()
    {
        BindScreenStatusBarText();
        screenStatusBarText = "Initialized";
    }

    public string ScreenStatusBarText
    {
        get { return screenStatusBarText; }
        set
        {
            screenStatusBarText = value;
            OnPropertyChanged("StatusBarText");
        }
    }

    private void BindScreenStatusBarText()
    {

        Binding b = new Binding();
        b.Source = screenStatusBarText;
        b.Mode = BindingMode.OneWay;
        b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        b.Path = new PropertyPath("StatusBarText");
        MainWindow.mainWindow.StatusBarText.SetBinding(TextBlock.TextProperty, b);

        MainWindow.mainWindow.StatusBarText.DataContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void OnPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(
                this, new PropertyChangedEventArgs(propName));
    } 
}

我的主要:

public partial class MainWindow : Window
{
    public static StatusInfo status;
    public MainWindow()
    {
        InitializeComponent();
        SourceInitialized += MainWindow_SourceInitialized;
    }

    private void MainWindow_SourceInitialized(object sender, EventArgs e)
    {
        SetUpDisplay();
    }

    private void SetUpDisplay()
    {
            status = new StatusInfo();
    }
}

【问题讨论】:

  • 你能改写吗我在StatusInfo的构造函数中设置了DataContext = this并且没有工作。我不清楚
  • 为什么不在 XAML 中建立绑定?您的方法看起来,嗯,倒退...也就是说,乍一看,我发现您没有正确使用 Binding.Source 属性。请参阅其文档 (msdn.microsoft.com/en-us/library/…) 以了解此属性的用途。此外,绑定的 PropertyPath 并不真正匹配任何东西。如果您想坚持在代码隐藏中构建/创建绑定,则需要格外注意。
  • 我没看到你在哪里设置 DataContext ?
  • WPF/UWP 和 XAML 在设计时考虑了 MVVM 模式。这看起来不像 MVVM 模式。虽然您可以使用其他方法,但这样做会丢失大约 90% 的功能,并且在其他任何地方都会遇到问题。多年前我写了一篇关于 MVVM 的简短介绍:social.msdn.microsoft.com/Forums/vstudio/en-US/… |希望切换到它对您有所帮助。
  • 旁注:在你的二传手中,你可能想先做:if (value == screenStatusBarText) return;

标签: c# wpf data-binding inotifypropertychanged textblock


【解决方案1】:

在 XAML 中设置绑定,而不是在后面的代码中:

<TextBlock Text="{Binding ScreenStatusBarText}" />

并使用类似的视图模型

public class StatusInfo : INotifyPropertyChanged
{
    private string screenStatusBarText = "Initialized";

    public string ScreenStatusBarText
    {
        get { return screenStatusBarText; }
        set
        {
            screenStatusBarText = value;
            OnPropertyChanged(nameof(ScreenStatusBarText));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this,
            new PropertyChangedEventArgs(propertyName));
    }
}

将视图模型类的实例分配给 MainWindow 的 DataContext:

private readonly StatusInfo statusInfo = new StatusInfo();

public MainWindow()
{
    InitializeComponent();
    DataContext = statusInfo;
}

您现在可以在以后的任何时间访问视图模型类,例如在 MainWindow 元素的事件处理程序中:

statusInfo.ScreenStatusBarText = "Something";

【讨论】:

  • 我有多个选项卡,每个选项卡上都有多个组件。使用 DataContext = statusInfo;将意味着下一行将是 DataContext = anothercomponent;我将如何处理许多组件?
  • 将 StatusInfo 和其他视图模型属性放在“外部”视图模型中。然后绑定Text="{Binding StatusInfo.ScreenStatusBarText}"
  • 现在它有时可以工作,但不是每次都更新。
  • 不确定你的意思。你设置了 ScreenStatusBarText,但 UI 没有更新?
  • 是的,我将 ScreenStatusBarText 设置为不同的值,它可能会更改 10 次。
【解决方案2】:

我认为您将很难在后面的代码中进行绑定。

话虽如此,关于为什么您的PropertyChanged 值为空。您只是打错了字,因为您正在通知订阅者不存在的属性已更改。避免此类拼写错误的一种解决方案是使用nameof

public string ScreenStatusBarText
{
    get { return screenStatusBarText; }
    set
    {
        screenStatusBarText = value;
        OnPropertyChanged(nameof(ScreenStatusBarText));
    }
}

我想到你可能也意味着你的事件是空的。这仅仅意味着您没有任何订阅者。见Why is my "Event" always null?

private void OnPropertyChanged(string propertyName)
{
    var handler = PropertyChanged;

    if (handler != null) // I have a subscriber.
        handler(this, new PropertyChangedEventArgs(propertyName));
}

【讨论】:

    猜你喜欢
    • 2014-06-15
    • 2010-12-03
    • 2011-10-13
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多