在键入c#时显示计算结果(类似于Javafx中的深层绑定))

时间:2014-09-04 06:17:32

标签: c# wpf binding

我正在寻找在键入其他文本框时更新TextBox TextProperty的可能性。 我有一对双属性,都是通过Textboxes输入的,我使用Double Properties获得了1个ReadOnly属性来做一些数学并返回结果。 我希望该结果显示在ReadOnly TextBox(WPF)中,并且在键入/更改输入参数TextBox时它应该自动更新。

在我使用JavaFX的过去几年里,我可以使用深度绑定来做到这一点:

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

          }
     };

如果更改了结果并且结果自动更新,则会自动检查带有super.bind(...)的Dependencies状态。

现在我只是想在C#中意识到这一点。

如上所述,我使用了几个属性。还实现了INotifyPropertyChanged。所以PropA,B和C在设置时声明OnPropertyChanged(“PropA”)。计算在像

这样的Readonly属性中完成
public Double MathProp
{
    get
    {
         return PropA*PropB/PropC;
    }
}

我通过Code将它绑定到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);

我使用显式触发器来执行“BruteForce” - 并在KeyEvent发生时手动更新它。但它只是不能很好地工作,我不喜欢那种解决问题的方法。必须有一个更优雅的方式。我希望你能指出我正确的方向。 我想过使用转换器而不是ReadOnly属性来进行计算。但我不是在转换我只是做一些数学而不是改变类型。

如果你能得到一些提示,我会很高兴的。

由于

1 个答案:

答案 0 :(得分:3)

好的,让我把它分成几部分:

  

我去年与JavaFX合作

忘记java。

java的方法非常低劣(就像java中的其他所有方法一样),因为UI与其背后的应用程序逻辑之间存在紧密耦合。

如果您正在使用WPF,强烈建议您留下您可能从古老的遗留技术中学到的所有方法,并理解并接受The WPF Mentality(这会变得非常重复)。< / p>

基本上,在WPF中,您不会将“计算”或其他不属于UI的代码放入与UI相关的类中。相反,您创建一个与UI完全无关的正确ViewModel并包含您需要显示的任何数据,以及您需要对其执行的逻辑,然后只需使用DataBinding填充< strong> XAML - 包含此类数据的用户界面。

所以,基本上,按照你的评论,这是你正在尝试实现的正确方法,在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>

代码背后:

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

        DataContext = new ViewModel();
    }
}
  • 注意我是如何在第一个和第二个绑定上设置UpdateSourceTrigger=PropertyChanged的。这会导致绑定在目标更改时立即更新值源(这意味着它在每次按键时都会完成)。

  • 另请注意,ViewModel必须Implement INotifyPropertyChanged才能正确支持双向WPF数据绑定。

  • 注意逻辑如何与UI完全分离,它实际上是简单,简单属性和INotifyPropertyChanged 。不需要对绑定框架或愚蠢的@override(无论这意味着什么)样板进行奇怪的操作。

  • 另请参阅我是如何使用XAML而不是使用过程代码来定义 UI,然后使用简单的DataBinding将其连接到基础数据。在WPF中,不鼓励和不需要操作过程代码中的UI元素。

  • WPF Rocks。 C#Rocks。 java是遗产

  • 如果您需要进一步的帮助,请与我们联系。