绑定到静态属性

我很难将一个简单的静态字符串属性绑定到 TextBox。

下面是具有 static 属性的类:

public class VersionManager
{
private static string filterString;


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

在 xaml 中,我只想将这个静态属性绑定到一个 TextBox:

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

所有内容都会编译,但是在运行时,我会遇到以下异常:

无法在属性中转换值 “ Source”转换为类型为 系统,视窗,标记,静态扩展。 目标错误 “ System. Windows. Data. Binding” 标记文件标记文件 ‘ BurnDisk; Component/selectversionpagefunction.xaml’ 线路57位置29。

知道我哪里做错了吗?

197718 次浏览

你不能绑定到这样的静态。由于不涉及 DependencyObject(或实现 INotifyPropertyChanged的对象实例) ,绑定基础结构无法获得更新通知。

如果该值没有改变,只需丢弃绑定,直接在 Text属性中使用 x:Static。将下面的 app定义为 VersionManager 类的命名空间(和程序集)位置。

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

如果该值确实发生了变化,我建议创建一个单例来包含该值并绑定到该值。

单例模式的一个例子:

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

如果绑定需要是双向的,则必须提供路径。

对静态属性进行双向绑定有一个技巧,前提是该类不是静态的: 在资源中声明该类的一个虚拟实例,并将其用作绑定的源。

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


<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>

在.NET 4.5中,可以绑定到静态属性 继续读

可以使用静态属性作为数据绑定的源 数据绑定引擎识别属性的值在 引发静态事件。例如,如果 SomClass 类定义了一个 可以定义静态事件 当 MyProperty 的值更改时引发。静态事件 可使用以下任何一种签名:

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

注意,在第一种情况下,该类公开一个名为 PropertyNameChanged,它将 EventArgs 传递给事件处理程序。 在第二种情况下,该类公开名为 将 PropertyChangedEventArgs 传递给 实现静态属性的类可以选择 使用任一方法引发属性更改通知。

你可以使用 ObjectDataProvider类和它的 MethodName属性。它可以看起来像这样:

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

声明的对象数据提供程序可以这样使用:

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

如果您正在使用本地资源,您可以参考以下内容:

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

绑定 static属性可能有两种方式/语法。如果 PMainWindow类中的 static属性,那么 textboxbinding将是:

1.

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

2.

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

看看我的项目 CalcBinding,它提供了用 Path 属性值编写复杂表达式,包括静态属性、源属性、 Math 和其他。所以,你可以这样写:

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

祝你好运!

从 WPF 4.5开始,您可以直接绑定到静态属性,并且当属性发生更改时,绑定会自动更新。您确实需要手动连接更改事件来触发绑定更新。

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


}

现在可以像绑定其他属性一样绑定静态属性:

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

对于.NET 4.5 + 来说是正确的变体

C # 代码

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 绑定(注意大括号是() ,而不是{})

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

最简洁的回答(. net 4.5及更高版本) :

    static public event EventHandler FilterStringChanged;
static string _filterString;
static public string FilterString
{
get { return _filterString; }
set
{
_filterString= value;
FilterStringChanged?.Invoke(null, EventArgs.Empty);
}
}

及 XAML:

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

不要忽略括号

另一种解决方案是创建一个普通类,该类实现 PropertyChanger,如下所示

public class ViewProps : PropertyChanger
{
private string _MyValue = string.Empty;
public string MyValue
{
get {
return _MyValue
}
set
{
if (_MyValue == value)
{
return;
}
SetProperty(ref _MyValue, value);
}
}
}

然后在不常用的地方创建类的静态实例

public class MyClass
{
private static ViewProps _ViewProps = null;
public static ViewProps ViewProps
{
get
{
if (_ViewProps == null)
{
_ViewProps = new ViewProps();
}
return _ViewProps;
}
}
}

现在将其用作静态属性

<TextBlock  Text="{x:Bind local:MyClass.ViewProps.MyValue, Mode=OneWay}"  />

如果需要,这里是 PropertyChanger 的实现

public abstract class PropertyChanger : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;


protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;


storage = value;
OnPropertyChanged(propertyName);
return true;
}


protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

假设您有一个类,如下所示:

public static class VersionManager
{
public static string FilterString;
}

您可以这样绑定静态变量:

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