0

i'm looking for a possibility to Update a TextBox TextProperty while typing in an other Textbox. I got a Couple of Double Properties, all entered via Textboxes and i got 1 ReadOnly Property using the Double Properties for doing some Math and returning the result. I want that result to be displayed in a ReadOnly TextBox (WPF) and it should update automatically when typing/changing an Input Parameter TextBox.

As i worked with JavaFX the last years i could use a deepbinding to do that:

DoubleBinding calcBind = new DoubleBinding(){
     {
          super.bind(PropA, PropB, PropC);
     }
          @Override
          protected double computeValue(){
              return (PropA * PropB / PropC)

          }
     };

The Dependencies statet with super.bind(...) are automatically checked if they changed and the result is automatically updated.

Now i'm just lookin for a possibility to realize that in C#

As said i am using a couple of properties. Also INotifyPropertyChanged is implemented. So PropA, B and C stating OnPropertyChanged("PropA") when set. The Calculation is done in a Readonly Property like

public Double MathProp
{
    get
    {
         return PropA*PropB/PropC;
    }
}

I am Binding it via Code to a TextBox TextProperty.

Binding mathBinding = new Binding
{
    Source = ObjectHolding.MathProp,
    Path = new PropertyPath("MathProp"),
    UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
    Mode = BindingMode.OnyWay
};

TextBox txtMathBox = new TextBox();
txtMathBox.SetBinding(TextBox.TextProperty, mathBinding);

I used the Explicit Trigger to do it the "BruteForce"-Way and updating it manually when a KeyEvent occurs. But its just not working very well and i dont like that way of resolving the problmen. There has to be a more elegant way. I hope u could point me in the right direction. I thought about using a converter instead of a ReadOnly Property to do the calculations. But i am not converting i am just doing some math and not changing the types.

Would be glad if u got some hints for me.

Thanks

  • 1
    As always, java's approach is inferior, burdensome, hacked together rather than well-designed. In WPF you don't put "calculations" in the UI because the UI is NOT responsible to perform any sort of calculations. WPF enables SEPARATION of UI and logic via MVVM, something that java hasn't even realized (and still thinks it's 1990). – Federico Berasategui Sep 04 '14 at 06:24
  • i know about mvvm but this is a simple 1-man tool thats calculating some stuff from user-input. there is no need using a mvvm purist design, and complaining about java isnt helping me anyway ;-) – user2959817 Sep 04 '14 at 06:31
  • `there is no need using a mvvm purist design` - why don't you keep your bruteforce approach then? – Federico Berasategui Sep 04 '14 at 06:32
  • cause its not working the way i want it to work. and there is no need in discussing of java is back in the 90s. if there is a good mvvm aproach solving the prob i'll use it – user2959817 Sep 04 '14 at 06:35
  • and stating u can seperate ui and logic simply isnt solving my problem. i need an approach solving the auto-update thing. no matter if i set the binding to the property in the code behind or in xaml. – user2959817 Sep 04 '14 at 06:42

1 Answers1

3

Ok, let me split this into parts:

As i worked with JavaFX the last years

Forget java.

java's approach is tremendously inferior (just as everything else in java), due to the tight coupling that occurs between your UI and the application logic behind it.

If you're working with WPF, it is strongly recommended that you leave behind any and all approaches you might have learned from archaic, legacy technologies and understand and embrace The WPF Mentality (this is getting very repetitive).

Basically, in WPF you don't put "calculations" or other code that doesn't really belong into the UI into UI-related classes. Instead, you create a proper ViewModel which is completely agnostic from the UI and contains whatever data you need to display, and the logic you need to perform on it, and then simply use DataBinding to populate the XAML-defined UI with such data.

So, basically, this is the correct way to do what you're trying to achieve, as per your comments, in WPF:

public class ViewModel : INotifyPropertyChanged
{
    private double _value1;
    private double _value2;
    private double _result;

    public double Value1
    {
        get { return _value1; }
        set
        {
            _value1 = value;
            OnPropertyChanged();
            OnPropertyChanged("Result");
        }
    }

    public double Value2
    {
        get { return _value2; }
        set
        {
            _value2 = value;
            OnPropertyChanged();
            OnPropertyChanged("Result");
        }
    }

    public double Result
    {
        get { return Value1*Value2; }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) 
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Text="{Binding Value1, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding Value2, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding Result, Mode=OneWay}" IsReadOnly="True"/>
    </StackPanel>
</Window>

Code behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new ViewModel();
    }
}
  • Notice how I'm setting UpdateSourceTrigger=PropertyChanged on the first and second bindings. This causes the binding to update the value source immediately when the target changes (which means it's being done at every key press).

  • Also notice that the ViewModel must Implement INotifyPropertyChanged in order to properly support two-way WPF DataBinding.

  • Notice how the logic is completely decoupled from the UI and it's really Simple, Simple Properties and INotifyPropertyChanged. No need for bizarre manipulations of the binding framework or stupid @override (whatever that means) boilerplate.

  • Also see how I'm using XAML rather than procedural code to Define the UI, and then simple DataBinding to connect it to the underlying data. In WPF, manipulating UI elements in procedural code is discouraged and unneeded.

  • WPF Rocks. C# Rocks. java is legacy.

  • Let me know if you need further help.

Community
  • 1
  • 1
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • thanks. i'll try that and let u know if i got it to work – user2959817 Sep 04 '14 at 06:48
  • thanks it works. think my problem was mixing using a viewmodel and putting some ui stuff in the codebehind wich cannot implement inotifypropertychanged itself (java approach is still in me ;-) ). – user2959817 Sep 04 '14 at 07:24
  • btw u can seperate ui and logic in java as well using javafx wich ui is xml based and using it with the pattern u want it to use. i'm sure u can implement an mvvm approach (but not as easy as in c#/wpf) – user2959817 Sep 04 '14 at 07:26
  • @user2959817 with some more effort, you can also implement MVVM in COBOL or similar technologies, however using legacy technologies makes absolutely no sense in my opinion. – Federico Berasategui Sep 04 '14 at 07:28