0

say I have this control:

public partial class bloc999 : UserControl
{
 bloc999Data mainBlock = new bloc999Data();

 public bloc999()
 {
  InitializeComponent();
  mainBlock.txtContents = "100";

  base.DataContext = mainBlock;
 }
}

in the xaml:

    <TextBox Margin="74,116,106,0" Name="txtContents" 
Text="{Binding Path=txtContents, UpdateSourceTrigger=PropertyChanged,Mode = TwoWay}" />
    <TextBox Margin="74,145,106,132" Name="txtContents2" 
Text="{Binding Path=txtContents2, UpdateSourceTrigger=PropertyChanged,Mode = TwoWay}" />

Then I have this class:

public class bloc999Data : INotifyPropertyChanged
    {
     string _txtContents;
     string _txtContents2;

     public event PropertyChangedEventHandler PropertyChanged;

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

     public string txtContents2
     {
            get
            {
              return this._txtContents2;
            }
            set
            {
                if (int.Parse(value) > int.Parse(this._txtContents))
                {
                    this._txtContents2 = "000";
                }
                else
                    this._txtContents2 = value;

                NotifyPropertyChanged("txtContents2");
            }
        }

        public string txtContents 
        {
            get
            {
                return this._txtContents;
            }
            set 
            {
                this._txtContents = value;
                NotifyPropertyChanged("txtContents");
            } 
        }
    }

Ok now say I have A button on the form and I do this in the code:

mainBlock.txtContents2 = "7777777";

It puts 000 in the textbox, but If i just type in manually, in the textbox (txtContents2), the setter code is called but for some reason the textboxes value does not change, the instance value does change. help?

2 Answers 2

1

I believe it's just because the value is changing within the context of the data binding operation, so WPF just ignores it because it knows the value is changing and thinks the event is superfluous. What it doesn't know is that you've gone and changed the value from the value WPF has to something else again.

If you do the notification in a separate message then WPF will process it outside the context of the current data binding operation and will thus pick up the change:

if (int.Parse(value) > int.Parse(this._txtContents))
{
    this._txtContents2 = "000";

    // notify WPF of our change to the property in a separate message
    Dispatcher.BeginInvoke((ThreadStart)delegate
    {
        NotifyPropertyChanged("txtContents2");
    });
}
else
{
    this._txtContents2 = value;
    NotifyPropertyChanged("txtContents2");
}

This assumes your view model has access to the Dispatcher. An example of how to do so is shown in my blog post on a base ViewModel class.

Sign up to request clarification or add additional context in comments.

2 Comments

I just tried this, but for some reason it works with BeginInvoke, but not with Invoke...
Sorry, I meant BeginInvoke - edited. I think Invoke will only work if you set the DispatcherPriority to something lower than DataBind.
0

I was having similar problem earlier here

In your usercontrol, update Binding and set UpdateSourceTrigger to Explicit

<TextBox Margin="74,145,106,132" x:Name="txtContents2" TextChanged="txtContents2_TextChanged"

Text="{Binding Path=txtContents2, UpdateSourceTrigger=Explicit,Mode = TwoWay}" />

then in the TextChanged event handler update the binding manually by validating the input. move validation logic from property txtContent2's setter in bloc999Data in this event handler

    private void txtContents2_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (int.Parse(txtContents2.Text) > int.Parse(mainBlock.txtContents))
        {
            mainBlock.txtContents2 = "000";
            txtContents2.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
        }
        else
        {
            mainBlock.txtContents2 = txtContents2.Text;
            txtContents2.GetBindingExpression(TextBox.TextProperty).UpdateSource();
        }
    }

and it works.

Hope it helps!!

1 Comment

This works, but I actually needed my code to stay inside my class, and from it I dont have acces to my TextBox, so I cant update it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.