views:

3615

answers:

2

I'm having a hard time binding a simple static string property to a text box.

Here's the class with the static property:

public class VersionManager
{
    private static string filterString;

    public static string FilterString
    {
        get { return filterString; }
        set { filterString = value; }
    }
}

In my xaml, I just want to bind this static property to a text box:

<TextBox>
    <TextBox.Text>
        <Binding Source="{x:Static local:VersionManager.FilterString}"/>
    </TextBox.Text>
</TextBox>

Everything compiles, but at run time, I get the following exception:

Cannot convert the value in attribute 'Source' to object of type 'System.Windows.Markup.StaticExtension'. Error at object 'System.Windows.Data.Binding' in markup file 'BurnDisk;component/selectversionpagefunction.xaml' Line 57 Position 29.

Any idea what I'm doing wrong?

+7  A: 

You can't bind to a static like that. There's no way for the binding infrastructure to get notified of updates since there's no DependencyObject (or object instance that implement INotifyPropertyChanged) involved.

If that value doesn't change, just ditch the binding and use x:Static directly inside the Text property.

If the value does change, I'd suggest creating a singleton to contain the value and bind to that.

An example of the singleton:

public class VersionManager : DependencyObject {
    public static readonly DependencyProperty FilterStringProperty =
        DependencyProperty.Register( "FilterString", typeof( string ),
        typeof( VersionManager ), new UIPropertyMetadata( "no version!" ) );
    public string FilterString {
        get { return (string) GetValue( FilterStringProperty ); }
        set { SetValue( FilterStringProperty, value ); }
    }

    public static VersionManager Instance { get; private set; }

    static VersionManager() {
        Instance = new VersionManager();
    }
}


<TextBox Text="{Binding Source={x:Static local:VersionManager.Instance}, Path=FilterString}"></TextBox>
Adam Sills
Really? I've been able to do bind to the static Int32.MaxValue which is very similar to my sample:<TextBox Text={Binding Source={x:Static sys:Int32.MaxValue}, Mode=OneWay}" />Is that working because it's one way?
Anthony Brien
Yeah, any two way binding requires a Path property value on the binding. Source needs to be an object that contains the property specified by Path.Specifying OneWay removes that restriction.
Adam Sills
Also, sorry for the late update, but I updated the above answer with a sample.
Adam Sills
Is there a way to bind a static string. I have a mutibinding and one of the input is a fixed string.
Nitin Chaudhari
+9  A: 

If the binding needs to be two-way, you must supply a path. There's a trick to do two-way binding on a static property, provided the class is not static : declare a dummy instance of the class in the resources, and use it as the source of the binding.

<Window.Resources>
    <local:VersionManager x:Key="versionManager"/>
</Window.Resources>
...

<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>
Thomas Levesque
This answer is more appropriate to my case because I don't want to introduce DependencyObject to my source class. Thanks for the tip!
Anthony Brien
Note that will enable your text box to push the value back into the static property, but will not update the textbox when the source value changes.
Adam Sills
That's fine, I just needed the binding from the textbox to the Source in this case. If I want the binding to work the other way, I'm aware of the need for one of these methods: INotifyPropertyChanged, <PropertyName>Changed event or dependency property.
Anthony Brien