0

I have a global class to be access by WPF page/window. The element in the window has been binding to datacontext. At first load, the value of player 1 can show "10" but when I press button and increase the value, nothing were updated

This is the first stack child inside stackpanel parent:-

<StackPanel x:Name="Stage1_Player1_Stack" DataContext="{Binding Stage1_Player1}" Margin="0,0,15,0">
    <TextBlock Margin="0,0,0,5" FontSize="16" FontWeight="Bold">Player 1</TextBlock>
    <materialDesign:Card x:Name="Stage1_Player1_Card" VerticalAlignment="Stretch" FontWeight="Bold" FontSize="16">
        <TextBlock x:Name="Stage1_Player1_Number" TextWrapping="Wrap" TextAlignment="Center" Text="{Binding Stage1Data.SelectedNumber, UpdateSourceTrigger=Explicit}" Padding="10" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Margin="0,5"/>
    </materialDesign:Card>
</StackPanel>
<!-- There will be more than 1 stack at max 10 players-->

On new window instance, I will initiate value(which will be retrieve from database. For testing, I hardcode):-

public MainWindow()
{
    InitializeComponent();
    GetPlayerData();
    DataContext = new
    {
        Stage1_Player1 = GlobalData.Player1Data,
    };

}
public void GetPlayerData()
{
    GlobalData.Player1Data = new Player
    {
        Stage1Data = new Stage1
        {
            SelectedNumber = "10"
        }
    };
}
private void BtnNext_Click(object sender, RoutedEventArgs e)
{
    int value = Convert.ToInt32(GlobalData.Player1Data.Stage1Data.SelectedNumber);
    GlobalData.Player1Data.Stage1Data.SelectedNumber = (value + 1).ToString();

    System.Windows.Data.BindingExpression binding = Stage1_Player1_Number.GetBindingExpression(TextBlock.TextProperty);
    binding.UpdateSource();
}

This is my global class file where I stuck on how to implement the PropertyChanged:-

public class GlobalData : INotifyPropertyChanged
{
    public static Player Player1Data { get; set; }
    public static Player Player2Data { get; set; }
    public static Player Player3ata { get; set; }
    public static Player Player4Data { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}
public class Player
{
    public Stage1 Stage1Data { get; set; }
    public Stage2 Stage2Data { get; set; }
    public Stage3 Stage3Data { get; set; }
    public Stage4 Stage4Data { get; set; }
}
public class Stage1
{
    public string SelectedNumber { get; set; }
}
public class Stage2
{
    public string SelectedNumber { get; set; }
    public string TotalAnswer { get; set; }
}
public class Stage3
{
    public string SelectedNumber { get; set; }
    public string GuessNumber { get; set; }
    public string CurrentPoint { get; set; }
    public string TotalAnswerCorrect { get; set; }
}
public class Stage4
{
    public string SelectedNumber { get; set; }
    public List<string> NumberSelectionList { get; set; }
}

How to let binding textblock know that SelectedNumber value has change?

I try to refer from Bind value from one class to another value in another class, Implementing INotifyPropertyChanged for nested properties but I'm totally dummies in binding things so I cannot guess the way to make it work for object class. I have done before on the propertychanged on the same page only but never try on object class like currently.

EDITED

public static class GlobalData

public static Player Player1Data
{
    get => _Player1Data;
    set
    {
        _Player1Data = value;
        OnStaticPropertyChanged("Player1Data");
    }
}
private static Player _Player1Data { get; set; }
public static event PropertyChangedEventHandler StaticPropertyChanged;
private static void OnStaticPropertyChanged(string propertyName)
{
    StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}

XAML:-

<TextBlock x:Name="Stage1_Player1_Number" Text="{Binding Path=Player1Data.Stage1Data.SelectedNumber}"/>
Luiey
  • 843
  • 2
  • 23
  • 50
  • Implementing INotifyPropertyChanged won't work for static properties (what you already realized because you don't know where to call NotifyPropertyChanged). You need a `StaticPropertyChanged` event as shown in the answer to the original question. Moreover, you should not implement INotifyPropertyChanged at all, and instead declare the class as static. – Clemens Nov 14 '19 at 10:55
  • @Clemens urmm I have try your answer as my edited. Does it correct? Currently it loaded the binding number 10 to view. But when I manipulate and change the value, it does not changed. Is it wrong implementation? I have try `Text="{Binding Path=(MyNamespace:Player1Data.Stage1Data.SelectedNumber})"` but got exception on initialize component. – Luiey Nov 15 '19 at 02:01
  • That seems to be a different problem. Ask another question with the exact details of that exception. – Clemens Nov 15 '19 at 06:48

0 Answers0