Binding to static property

Binding to static property



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?




9 Answers
9



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"/>






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
Jun 2 '09 at 15:30






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
Jun 2 '09 at 16:45






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
Jun 2 '09 at 20:34






Note: This solution won't work in an MVVM situation, as you generally don't have access to the types of the objects you're binding to.

– acron
Oct 11 '13 at 9:06







@thomas I would love to get this to work for me but cannot. I posted my dilemma as another question here: stackoverflow.com/questions/34656670/…

– Andrew Simpson
Jan 7 '16 at 14:01



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.


DependencyObject


INotifyPropertyChanged



If that value doesn't change, just ditch the binding and use x:Static directly inside the Text property. Define app below to be the namespace (and assembly) location of the VersionManager class.


x:Static


Text


app


<TextBox Text="x:Static app:VersionManager.FilterString" />



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"/>






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
Jun 1 '09 at 19:36






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
Jun 1 '09 at 21:30






Also, sorry for the late update, but I updated the above answer with a sample.

– Adam Sills
Jun 1 '09 at 21:37






Is there a way to bind a static string. I have a mutibinding and one of the input is a fixed string.

– Nitin Chaudhari
Jul 9 '10 at 11:12



In .NET 4.5 it's possible to bind to static properties, read more



You can use static properties as the source of a data binding. The
data binding engine recognizes when the property's value changes if a
static event is raised. For example, if the class SomeClass defines a
static property called MyProperty, SomeClass can define a static event
that is raised when the value of MyProperty changes. The static event
can use either of the following signatures:


public static event EventHandler MyPropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;



Note that in the first case, the class exposes a static event named
PropertyNameChanged that passes EventArgs to the event handler.
In the second case, the class exposes a static event named
StaticPropertyChanged that passes PropertyChangedEventArgs to the
event handler. A class that implements the static property can choose
to raise property-change notifications using either method.






Here's the link in case anyone wants to read more. Microsoft took it down, but it's on web archive here. web.archive.org/web/20131129053934/http://msdn.microsoft.com/…

– matrixugly
Apr 11 '16 at 1:02






some examples pleaseeee...

– user1034912
Mar 23 '17 at 12:50






This answer pointed me in the right direction, but it still took a while to work out the details without an example. I've written up an example based on the original code.

– Matt
Nov 22 '17 at 6:22




As of WPF 4.5 you can bind directly to static properties and have the binding automatically update when your property is changed. You do need to manually wire up a change event to trigger the binding updates.


public class VersionManager

private static String _filterString;

/// <summary>
/// A static property which you'd like to bind to
/// </summary>
public static String FilterString

get

return _filterString;


set

_filterString = value;

// Raise a change event
OnFilterStringChanged(EventArgs.Empty);



// Declare a static event representing changes to your static property
public static event EventHandler FilterStringChanged;

// Raise the change event through this static method
protected static void OnFilterStringChanged(EventArgs e)

EventHandler handler = FilterStringChanged;

if (handler != null)

handler(null, e);



static VersionManager()

// Set up an empty event handler
FilterStringChanged += (sender, e) => return; ;





You can now bind your static property just like any other:


<TextBox Text="Binding Path=(local:VersionManager.FilterString)"/>



You can use ObjectDataProvider class and it's MethodName property. It can look like this:


ObjectDataProvider


MethodName


<Window.Resources>
<ObjectDataProvider x:Key="versionManager" ObjectType="x:Type VersionManager" MethodName="get_FilterString"></ObjectDataProvider>
</Window.Resources>



Declared object data provider can be used like this:


<TextBox Text="Binding Source=StaticResource versionManager" />



If you are using local resources you can refer to them as below:


<TextBlock Text="Binding Source=x:Static prop:Resources.PerUnitOfMeasure" TextWrapping="Wrap" TextAlignment="Center"/>



There could be two ways/syntax to bind a static property. If p is a static property in class MainWindow, then binding for textbox will be:


static


static


MainWindow


binding


textbox



1.


<TextBox Text="x:Static local:MainWindow.p" />



2.


<TextBox Text="Binding Source=x:Static local:MainWindow.p,Mode=OneTime" />



Look at my project CalcBinding, which provides to you writing complex expressions in Path property value, including static properties, source properties, Math and other. So, you can write this:


<TextBox Text="c:Binding local:VersionManager.FilterString"/>



Goodluck!



Right variant for .NET 4.5 +



C# code


public class VersionManager

private static string filterString;

public static string FilterString

get => filterString;
set

if (filterString == value)
return;

filterString = value;

StaticPropertyChanged?.Invoke(null, FilterStringPropertyEventArgs);



private static readonly PropertyChangedEventArgs FilterStringPropertyEventArgs = new PropertyChangedEventArgs (nameof(FilterString));
public static event PropertyChangedEventHandler StaticPropertyChanged;



XAML binding (attention to braces they are (), not )


<TextBox Text="Binding Path=(yournamespace:VersionManager.FilterString)" />






Made a slight change to your code to properly call the EventHandler.

– MarqueIV
Sep 8 '18 at 0:41



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)