views:

32

answers:

2

I have what I think is a very simple databinding question (I'm still new to WPF). I have a class (simplified for this question)

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

In MainWindow.Xaml.cs I have a private member variable:

private ConfigurationData m_data;

and a method

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
}

In my MainWindow gui, I'd like to have a TextBox that displays m_data.BaudRate AND allows for two way binding. The user should be able to enter a value in the textbox, and the textbox should display new values that we're caused by "DoStuff()" method. I've seen tons of examples on binding to another property of a control on MainWindow, and binding to a datacollection, but no examples of binding to a property of another object. I would think that my example is about as simple as it get, with the nagging annoyance that I'm binding to an integer, not a string, and if possible, I would like the user to only be able to enter integers.
BTW I considered using a numeric up/down, but decided against it as there did not seem to be a lot of support/examples of non-commercial numeric up/down controls. Plus, it could be an awfully big range of numbers to spin through.

I think a pointer to one good example would get me on my way. Many thanks in advance, Dave

A: 

I'm sure there's a better way (please tell me!), but here's one way I cobbled together that works. It seems that there should be an easier way. For the property BaudRate use:

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
            }
        }
    }

For the XAML, I have no significant markup:

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

Now this is the messy part... Create class for validation:

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);
        }


    }
}

And then in the constructor of Window1 (MainWindow), have:

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);

All my attempts to do everything in markup failed. Better ways?

Dave

Dave