简体   繁体   中英

WPF C# PropertyChanged always null

I have played around with this for a while and decided to see if someone can help, I have set in the constructor of StatusInfo the DataContext = this and didn't work. When I write a string to ScreenStatusBarText it does call the OnPropertyChanged method but every time the PropertyChanged value is null. I The status block I have at the bottom of the screen. I have a tab section above this stack panel that has many components that use bindings and work.

Screen Code

<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>

Data Model:

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));
    } 
}

My main :

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();
    }
}

Set the Binding in XAML instead of code behind:

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

And use a view model like

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));
    }
}

with an instance of the view model class assigned to the MainWindow's DataContext:

private readonly StatusInfo statusInfo = new StatusInfo();

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

You may now access the view model class at any time later, eg in an event handler of an element of MainWindow:

statusInfo.ScreenStatusBarText = "Something";

I think your going to struggle doing your binding in code behind.

Having said that, with regards to why your PropertyChanged value is null. You've simply made a typo, as-is you're notifying subscribers that a property that doesn't exist has changed. One solution to avoid such typos is to use nameof .

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

It occurred to me you may also have meant that your event was null. This simply means you don't have any subscribers. See 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));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM