我很难将简单的静态字符串属性绑定到文本框。
这是具有静态属性的类:
public class VersionManager
{
private static string filterString;
public static string FilterString
{
get { return filterString; }
set { filterString = value; }
}
}
在我的xaml中,我只想将此静态属性绑定到文本框:
<TextBox>
<TextBox.Text>
<Binding Source="{x:Static local:VersionManager.FilterString}"/>
</TextBox.Text>
</TextBox>
所有内容都会编译,但在运行时,我会遇到以下异常:
无法转换属性中的值 '源'到类型的对象 'System.Windows.Markup.StaticExtension'。 对象出错 'System.Windows.Data.Binding'中 标记文件 'BurnDisk;组件/ selectversionpagefunction.xaml' 第57行第29位。
知道我做错了吗?
答案 0 :(得分:157)
如果绑定需要双向,则必须提供路径。如果类不是静态的,那么对静态属性进行双向绑定有一个技巧:在资源中声明类的虚拟实例,并将其用作绑定的源。
<Window.Resources>
<local:VersionManager x:Key="versionManager"/>
</Window.Resources>
...
<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>
答案 1 :(得分:98)
你无法绑定到那样的静态。绑定基础结构无法获得更新通知,因为没有涉及DependencyObject
(或实现INotifyPropertyChanged
的对象实例)。
如果该值没有改变,只需抛弃绑定并直接在x:Static
属性中使用Text
。将下面的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}"/>
答案 2 :(得分:38)
在.NET 4.5中,可以绑定到静态属性read more
您可以使用静态属性作为数据绑定的来源。该 如果a,则数据绑定引擎会识别属性值的变化 引发静态事件。例如,如果SomeClass类定义了一个 名为MyProperty的静态属性,SomeClass可以定义一个静态事件 当MyProperty的值发生变化时引发。静态事件 可以使用以下任一签名:
public static event EventHandler MyPropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
请注意,在第一种情况下,该类公开名为的静态事件 将EventArgs传递给事件处理程序的PropertyNameChanged。 在第二种情况下,该类公开名为的静态事件 将PropertyChangedEventArgs传递给的StaticPropertyChanged 事件处理程序实现静态属性的类可以选择 使用任一方法提出财产变更通知。
答案 3 :(得分:10)
从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)}"/>
答案 4 :(得分:8)
您可以使用ObjectDataProvider
类及其MethodName
属性。它看起来像这样:
<Window.Resources>
<ObjectDataProvider x:Key="versionManager" ObjectType="{x:Type VersionManager}" MethodName="get_FilterString"></ObjectDataProvider>
</Window.Resources>
声明的对象数据提供者可以像这样使用:
<TextBox Text="{Binding Source={StaticResource versionManager}}" />
答案 5 :(得分:7)
如果您使用的是本地资源,可以按以下方式参考:
<TextBlock Text="{Binding Source={x:Static prop:Resources.PerUnitOfMeasure}}" TextWrapping="Wrap" TextAlignment="Center"/>
答案 6 :(得分:6)
绑定static
属性可能有两种方法/语法。如果 p 是 static
类中的MainWindow
属性,则binding
的{{1}}将为:
<强> 1 强>
textbox
<强> 2 强>
<TextBox Text="{x:Static local:MainWindow.p}" />
答案 7 :(得分:2)
查看我的项目CalcBinding,它提供了在Path属性值中编写复杂表达式,包括静态属性,源属性,Math和其他。所以,你可以这样写:
<TextBox Text="{c:Binding local:VersionManager.FilterString}"/>
古德勒克!
答案 8 :(得分:2)
.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)}" />
答案 9 :(得分:0)
最佳答案(.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)}"/>
不要忽略括号
答案 10 :(得分:0)
如果您想遵循良好的约定,那么这些答案都很好,但是OP想要简单的东西,这也是我想要的,而不是处理GUI设计模式。如果您只想在基本的GUI应用程序中包含一个字符串,就可以随意更新即席更新,您可以直接在C#源代码中直接访问它。
假设您有这样一个非常基本的WPF应用程序MainWindow XAML,
<Window x:Class="MyWPFApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyWPFApp"
mc:Ignorable="d"
Title="MainWindow"
Height="200"
Width="400"
Background="White" >
<Grid>
<TextBlock x:Name="textBlock"
Text=".."
HorizontalAlignment="Center"
VerticalAlignment="Top"
FontWeight="Bold"
FontFamily="Helvetica"
FontSize="16"
Foreground="Blue" Margin="0,10,0,0"
/>
<Button x:Name="Find_Kilroy"
Content="Poke Kilroy"
Click="Button_Click_Poke_Kilroy"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Helvetica"
FontWeight="Bold"
FontSize="14"
Width="280"
/>
</Grid>
</Window>
这看起来像这样:
在MainWindow XAML的源代码中,您可能会遇到类似这样的事情,我们所做的全部工作都是通过textBlock.Text
的{{1}} / get
功能直接更改值:
set
然后,当您通过单击按钮触发该单击事件时,瞧! Kilroy出现:)
答案 11 :(得分:0)
另一种解决方案是创建一个普通的类,该类实现了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));
}
}