绑定到静态属性

Ant*_*ien 163 data-binding wpf xaml

我很难将简单的静态字符串属性绑定到文本框.

这是具有静态属性的类:

public class VersionManager
{
    private static string filterString;

    public static string FilterString
    {
        get { return filterString; }
        set { filterString = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的xaml中,我只想将此静态属性绑定到文本框:

<TextBox>
    <TextBox.Text>
        <Binding Source="{x:Static local:VersionManager.FilterString}"/>
    </TextBox.Text>
</TextBox>
Run Code Online (Sandbox Code Playgroud)

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

无法将属性"Source"中的值转换为"System.Windows.Markup.StaticExtension"类型的对象.标记文件'BurnDisk中的对象'System.Windows.Data.Binding'出错;组件/ selectversionpagefunction.xaml'第57行位置29.

知道我做错了什么吗?

Tho*_*que 161

如果绑定需要双向,则必须提供路径.如果类不是静态的,那么在静态属性上进行双向绑定有一个技巧:在资源中声明类的虚拟实例,并将其用作绑定的源.

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

<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>
Run Code Online (Sandbox Code Playgroud)

  • 请注意,将使您的文本框能够将值推回到静态属性中,但在源值更改时不会更新文本框. (5认同)

Ada*_*lls 103

你无法绑定到那样的静态.绑定基础结构无法获得更新通知,因为没有涉及DependencyObject(或实现的对象实例INotifyPropertyChanged).

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

<TextBox Text="{x:Static app:VersionManager.FilterString}" />
Run Code Online (Sandbox Code Playgroud)

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

单身人士的一个例子:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)
<TextBox Text="{Binding Source={x:Static local:VersionManager.Instance},
                        Path=FilterString}"/>
Run Code Online (Sandbox Code Playgroud)

  • 真?我已经能够绑定到静态Int32.MaxValue,这与我的样本非常相似:<TextBox Text = {Binding Source = {x:Static sys:Int32.MaxValue},Mode = OneWay}"/>是吗工作,因为这是一种方式? (4认同)
  • 是的,任何双向绑定都需要绑定上的Path属性值.Source必须是包含Path指定的属性的对象.指定OneWay会删除该限制. (2认同)

Jow*_*wen 38

在.NET 4.5中,可以绑定到静态属性,阅读更多内容

您可以使用静态属性作为数据绑定的源.如果引发静态事件,数据绑定引擎会识别属性值何时更改.例如,如果SomeClass类定义了一个名为MyProperty的静态属性,则SomeClass可以定义在My​​Property的值更改时引发的静态事件.静态事件可以使用以下任一签名:

public static event EventHandler MyPropertyChanged; 
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; 
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案为我指明了正确的方向,但在没有示例的情况下仍然需要一段时间才能弄清楚细节。我根据原始代码编写了一个[示例](/sf/answers/3319961081/)。 (2认同)

Mat*_*att 12

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

}
Run Code Online (Sandbox Code Playgroud)

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

<TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
Run Code Online (Sandbox Code Playgroud)

  • 路径定义中需要大括号,因为该属性是静态的,请参阅[此处](https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/propertypath-xaml-syntax?redirectedfrom=MSDN #singleattached) (2认同)

小智 8

你可以使用ObjectDataProviderclass及其MethodName属性.它看起来像这样:

<Window.Resources>
   <ObjectDataProvider x:Key="versionManager" ObjectType="{x:Type VersionManager}" MethodName="get_FilterString"></ObjectDataProvider>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

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

<TextBox Text="{Binding Source={StaticResource versionManager}}" />
Run Code Online (Sandbox Code Playgroud)


Edm*_*ton 7

如果您使用的是本地资源,可以参考如下:

<TextBlock Text="{Binding Source={x:Static prop:Resources.PerUnitOfMeasure}}" TextWrapping="Wrap" TextAlignment="Center"/>
Run Code Online (Sandbox Code Playgroud)


Kyl*_*Ren 7

绑定static属性可能有两种方法/语法.如果pstatic类中的属性MainWindow,那么bindingfor textbox将是:

1.

<TextBox Text="{x:Static local:MainWindow.p}" />
Run Code Online (Sandbox Code Playgroud)

2.

<TextBox Text="{Binding Source={x:Static local:MainWindow.p},Mode=OneTime}" />
Run Code Online (Sandbox Code Playgroud)


Ale*_*kov 6

.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;
}
Run Code Online (Sandbox Code Playgroud)

XAML 绑定(注意大括号是 (),而不是 {})

<TextBox Text="{Binding Path=(yournamespace:VersionManager.FilterString)}" />
Run Code Online (Sandbox Code Playgroud)


Sea*_*ean 5

最简单的答案(.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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

和 XAML:

    <TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
Run Code Online (Sandbox Code Playgroud)

不要忽视括号