开发者

Two Way Binding in WPF

开发者 https://www.devze.com 2023-01-04 12:57 出处:网络
I am (very) new to WPF and I have got a question regarding that. It may be a very stupid one, so please excuse me if that is the case.

I am (very) new to WPF and I have got a question regarding that. It may be a very stupid one, so please excuse me if that is the case.

I am doing a project where I am binding my textboxes, etc to static properties inside a singleton class. My problem is that the twoWay Binding is not working. When the textbox changes, I can see that the value of the property changes, but when the property changes, I can't see the textbox text changing.

To see what's going on I wrote a small app, with just the relevant code. Please find the code below.

In the code below, I am changing the text in the textbox and source property in various places and noted my observations. If someone can tell me what I am doing wrong and point me in the right direction, I would be very grateful.

I also tried INotifyPropertyChanged, but it gives problems because of the static property. Is there a different approach when implementing INotifyPropertyChanged for a static property.

Thanks in advance, Abhi.

XAML:

<Page x:Class="TestBindingApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Prefs="clr-namespace:TestBindingApp"
  xmlns:cm="clr-namespace:System.ComponentModel;assembly=System"
  xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
  xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
Title="Page1" Loaded="Page_Loaded">
<Page.Resources>
    <Prefs:Class1 x:Key="TClass"></Prefs:Class1>
</Page.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" Margin="15 5 5 0" Height="20">
        <TextBlock Name="txbBankNumber" Margin="50 0 0 0" Padding="2">Bank Account Number :</TextBlock>
        <TextBox Name="txtBankNumber" Margin="10 0 0 0" Width="100" MaxLength="8" HorizontalAlignment="Left">
            <TextBox.Text>
                <Binding Source="{StaticResource TClass}" Path="AccountNumber" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
                </Binding>
            </TextBox.Text>
        </TextBox>
    </StackPanel>

</Grid>

XAML.CS:

namespace TestBindingApp
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
    public Page1()
    {

        InitializeComponent();

        txtBankNumber.Text = "ABC";
 // I can see the property AccountNumber changing here
        Class1.AccountNumber = "123456";
 // Value in txtBankNumber doesn't change here
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        txtBankNumber.Text = "ABCDE";
 // I can see the property AccountNumber changing here

        Class1.AccountNumber = "12345678";
 // Value in txtBankNumber doesn't change here

    }
}

}

Class Class1:

using System.ComponentModel;

namespace TestBindingApp
{
public class Class1
{
    // Singleton ins开发者_如何学Gotance
    private static Class1 instance;
    private static string _accountNumber;
    public Class1()
    {

    }

    // Singleton instance read-only property
    public static Class1 Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Class1();
            }
            return instance;
        }
    }

    public static string AccountNumber
    {
        get
        {
            return _accountNumber;
        }
        set
        {
            if (value != _accountNumber)
            {
                _accountNumber = value;
            }
        }
    }
}

}

=====================

Couldn't post my updated code in the comments, so updating my original post.

Below is my updated code, which has the "if(PropertyChanged != null)", but it gives me an error - "An object reference is required for the non-static field, method, or property 'TestBindingApp.Class1.NotifyPropertyChanged(string)'". .

I have just started learning WPF, so if you could explain in detail, that would be very helpful. Thanks for your patience.

using System.ComponentModel;

namespace TestBindingApp
{
public class Class1: INotifyPropertyChanged
{
    // Singleton instance
    private static Class1 instance;
    private static string _accountNumber;
    public event PropertyChangedEventHandler PropertyChanged;

    public Class1()
    {

    }

    // Singleton instance read-only property
    public static Class1 Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Class1();
            }
            return instance;
        }
    }

    public static string AccountNumber
    {
        get
        {
            return _accountNumber;
        }
        set
        {
            if (value != _accountNumber)
            {
                _accountNumber = value;
                NotifyPropertyChanged("AccountNumber");
            }
        }
    }

    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    } 

}

}

==============

Updated 23rd June, 09:53 AM UK time

Hi Arcturus, I have changed the properties to non-static, but it is still not behaving as I expect it to. Am I expecting it to do something which it isn't meant to do, or am I doing something wrong. In the below code, I expected the textbox to show 12345678 (or maybe 123456) as the account number, but it still shows 123. In the debug mode, I can see PropertyChanged event executing correctly after each property change statement, but the value of the textbox doesn't change. Does the binding take affect only at the time of initialization (InitializeComponent()), or am I missing something here?

Page code-behind

namespace TestBindingApp
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
    public Page1()
    {
        Class1.Instance.AccountNumber = "123";
        InitializeComponent();
        Class1.Instance.AccountNumber = "123456";
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        Class1.Instance.AccountNumber = "12345678";
    }
}
}

Class1.cs

namespace TestBindingApp
{
public class Class1: INotifyPropertyChanged
{
    // Singleton instance
    private static Class1 instance;
    private static string _accountNumber;
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public Class1()
    {

    }

    // Singleton instance read-only property
    public static Class1 Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Class1();
            }
            return instance;
        }
    }

    public string AccountNumber
    {
        get
        {
            return _accountNumber;
        }
        set
        {
            if (value != _accountNumber)
            {
                _accountNumber = value;
                OnPropertyChanged("AccountNumber");
            }
        }
    }

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

}
}


You really need the INotifyPropertyChanged interface:

using System.ComponentModel;

namespace TestBindingApp
{
public class Class1
{
    // Singleton instance
    private static Class1 instance;
    private string _accountNumber;
    public Class1()
    {

    }

    // Singleton instance read-only property
    public static Class1 Instance
    {
    get
    {
        if (instance == null)
        {
        instance = new Class1();
        }
        return instance;
    }
    }

    public string AccountNumber
    {
    get
    {
        return _accountNumber;
    }
    set
    {
        if (value != _accountNumber)
        {
        _accountNumber = value;
            NotifyPropertyChanged("AccountNumber");
        }
    }
    }

        public event PropertyChangedEventHandler PropertyChanged;


    private void NotifyPropertyChanged(string property)
    {
        if(PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}


You call NotifyPropertyChanged from a static member, but NotifyPropertyChanged itself isn't static.

Two ways to solve: Either make AccountNumber NOT static or provide an instance for your call to NotifyPropertyChanged (e.g. "Instance.NotifyPropertyChanged(...)")

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号