简体   繁体   中英

How to bind a public property to a WPF TextBox.Text property

I've been struggling to bind a TextBox.Text to some object's public property but unfortunately I'm not quite there yet.

The actual XAML looks like:

<Window 
    <!-- skipped --> 
    xmlns:local="clr-namespace:Dotnet.Samples.Foobar"
    xmlns:system="clr-namespace:System;assembly=mscorlib">

    <Window.Resources>
        <local:Foobar x:Key="foobar" Foo="Lorem" Bar="Ipsum"
    </Window.Resources>
    <!-- skipped -->

        <TextBox Text="{Binding Source={StaticResource foobar}, Path=Foo}">
        <TextBox Text="{Binding Source={StaticResource foobar}, Path=Bar}">
        <!-- skipped -->
</Window>

With the data provider object being as simple as:

public class Foobar
{
    public string Foo { get; set; }
    public string Bar { get; set; }

    public Foobar()
    {

    }
}

I guess I'm sort of confused with WPF's various binding options and I'm probably mixing them up so any advice will be definitely appreciated.

EDIT -- All bindings are working ok, the remaining challenge is notifying changes from the Model to the ViewModel (the other way around works). I've committed the 'broken' code to an alternative repo: http://nanotaboada.svn.beanstalkapp.com/dotnet/trunk/Dotnet.Samples.Rijndael/

Feel free to checkout and I'd be very happy to hear about any feedback about this. Thanks much in advance

This looks fine except that I don't think the ObjectDataProvider is capable of reading default parameters. Try creating a Foobar constructor that has no arguments whatsoever.

Failing that, can you give us the error you're seeing?

What do you mean by "not quite there"? Everything looks fine to me except you're missing change notification in your Foobar class. Change it so that it implements INotifyPropertyChanged correctly and everything should work fine.

I think it's a problem with the parameters in the constructor. If you really need them you can write it like this:

<ObjectDataProvider x:Key="foobar" ObjectType="{x:Type abc:Foobar}" MethodName="Foobar1">
        <ObjectDataProvider.MethodParameters>
            <sys:String>my_param</sys:String>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

Which will also need this added: xmlns:sys="clr-namespace:System;assembly=mscorlib"

And then the Foobar class will be this:

public class Foobar
{
    public string Foo { get; set; }
    public string Bar { get; set; }

    public Foobar Foobar1(string param1 = "foo", string param2 = "bar")
    {
        Foobar f = new Foobar();
        f.Foo = param1;
        f.Bar = param2;
        return f;
    }
}

Get rid of / add params in the XAML as you need.

The XAML binding engine isn't finding an appropriate constructor to use, even though your constructor method parameters are optional. Therefore, you'll either have to pass in the values for the constructor, or create a parameterless constructor which sets the value of Foo to a default value, or don't use the ObjectDataProvider at all, and create an instance of your type directly as a resource.

...
xmlns:system="clr-namespace:System;assembly=mscorlib"
...

<!-- Either create an instance of your type, and you can initialise the property values, this will require a default parameterless constructor -->
<abc:Foobar x:Key="foobar2" Foo="Foo" />

<!-- or pass the optional parameter values into your existing constructor -->
<ObjectDataProvider x:Key="foobar" ObjectType="{x:Type abc:Foobar}">
  <ObjectDataProvider.ConstructorParameters>
    <system:String>Foo</system:String>
    <system:String>Bar</system:String>
  </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

Note that you'll only need to implement INotifyPropertyChanged if your bindings are going to be invalidated in code, and you need to notify the UI. If you aren't happy implementing this interface on your model types, then you can do this on your view models (assuming you're using MVVM), but then you'll need to find another mechanism to notify your view models when your model values change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM