5

非常に単純なデータバインディングの質問だと思います(私はまだWPFを初めて使用します)。私はクラスを持っています(この質問のために簡略化されています)

public class ConfigurationData
{
    public int BaudRate { get; set; } 
}

MainWindow.Xaml.csには、プライベートメンバー変数があります。

private ConfigurationData m_data;

と方法

void DoStuff()
{
   // do a bunch of stuff (read serial port?) which may result in calling...
   m_data.BaudRate = 300; // or some other value depending on logic
}

MainWindow GUIで、m_data.BaudRateを表示し、双方向のバインディングを可能にするTextBoxが必要です。ユーザーはテキストボックスに値を入力できる必要があり、テキストボックスには「DoStuff()」メソッドによって発生した新しい値が表示される必要があります。MainWindowのコントロールの別のプロパティへのバインド、およびデータコレクションへのバインドに関する例はたくさんありますが、別のオブジェクトのプロパティへのバインドの例はありません。私の例は、文字列ではなく整数にバインドしているという厄介な問題を伴う、ほぼ単純なものだと思います。可能であれば、ユーザーは整数のみを入力できるようにしたいと思います。
ところで、私は数値のアップ/ダウンを使用することを検討しましたが、非商用の数値のアップ/ダウンコントロールのサポート/例があまりないようだったので、それを拒否しました。さらに、スピンスルーするのは非常に大きな範囲の数値になる可能性があります。

一つの良い例へのポインタが私を道に連れて行ってくれると思います。よろしくお願いします、デイブ

4

3 に答える 3

19

この質問は古いものですが、良い質問であり、簡潔に答えられることはめったにありません。このページにたどり着いた他の人のために、簡単な解決策を提供しましょう。

双方向バインディングをサポートするには、ConfigurationDataプロパティの変更をサポートするように初期クラスを拡張する必要があります。そうしないと、変更がDoStuff()UI テキストボックスに反映されません。これを行う典型的な方法は次のとおりです。

using System.ComponentModel;
public class ConfigurationData : INotifyPropertyChanged
{
    private int _BaudRate;
    public int BaudRate
    {
        get { return _BaudRate; }
        set { _BaudRate = value; OnPropertyChanged("BaudRate"); }
    }

    //below is the boilerplate code supporting PropertyChanged events:
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

次のように、テキスト ボックス バインドを XAML に直接配置することにしました (DoStuff にもボタンを追加しました)。

<Canvas>
    <TextBox Width="96" Name="textBox1" Text="{Binding BaudRate}" />
    <Button  Width="96" Canvas.Top="25" Content="ChangeNumber" Click="DoStuff"/>
</Canvas>

トリッキーな部分は、これをすべて一緒に接着することです. そのためには、DataContext を定義する必要があります。メインウィンドウのコンストラクターでこれを行うことを好みます。コードは次のとおりです。

public partial class MainWindow : Window
{
    private ConfigurationData m_data;
    public MainWindow()
    {
        InitializeComponent();
        m_data = new ConfigurationData();
        this.DataContext = m_data;  // This is the glue that connects the
                                    // textbox to the object instance
    }

    private void DoStuff(object sender, RoutedEventArgs e)
    {
        m_data.BaudRate += 300;
    }
}
于 2011-08-10T21:53:59.627 に答える
0

もっと良い方法があると確信しています (教えてください!)。もっと簡単な方法があるはずです。プロパティ BaudRate には、次を使用します。

public int BaudRate
    {
        get
        { 
            return m_baudRate;
        }
        set 
        {
            if (value != m_baudRate)
            {
                m_baudRate = value;
                OnPropertyChanged("BaudRate");//OnPropertyChanged definition left out here, but it's pretty standard
            }
        }
    }

XAML については、重要なマークアップはありません。

<TextBox  Height="23" Margin="137,70,21,0" Name="textBox1" VerticalAlignment="Top"  />

これは厄介な部分です...検証用のクラスを作成します。

public class IntRangeRule : ValidationRule
{
    // See ValidationRule Class
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        try
        {
            if (value is int) // replace with your own logic or more robust handling...
            {
                return new ValidationResult(true, "Fine");
            }
            else
            {
                return new ValidationResult(false, "Illegal characters or ");
            }
        }

        catch (Exception e)
        {
            return new ValidationResult(false, "Illegal characters or " + e.Message);
        }


    }
}

そして、Window1 (MainWindow) のコンストラクターで、次のようにします。

Binding myBinding = new Binding("BaudRate");
        myBinding.NotifyOnValidationError = true;
        myBinding.Mode = BindingMode.TwoWay;
        ValidationRule rule = new IntRangeRule();
                    myBinding.ValidationRules.Add(rule);
        myBinding.Source = m_data; // where m_data is the member variable of type ConfigurationData
        textBox1.SetBinding(TextBox.TextProperty, myBinding);

マークアップですべてを実行しようとする試みはすべて失敗しました。より良い方法は?

デイブ

于 2010-10-08T14:44:00.077 に答える