単純な静的文字列プロパティをテキストボックスにバインドするのに苦労しています。
静的プロパティを持つクラスは次のとおりです。
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」のオブジェクトに変換できません。マークアップファイル 'BurnDisk; component/selectversionpagefunction.xaml'のオブジェクト 'System.Windows.Data.Binding'でのエラー行57位置29。
私が間違っていることを知っていますか?
バインディングを双方向にする必要がある場合は、パスを指定する必要があります。クラスが静的でない場合、静的プロパティで双方向バインディングを行うトリックがあります。リソースでクラスのダミーインスタンスを宣言し、バインディングのソースとして使用します。
<Window.Resources>
<local:VersionManager x:Key="versionManager"/>
</Window.Resources>
...
<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>
そのような静的にバインドすることはできません。 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}"/>
.NET 4.5では、静的プロパティにバインドできます 続きを読む
静的プロパティをデータバインディングのソースとして使用できます。データバインディングエンジンは、静的イベントが発生した場合にプロパティの値がいつ変更されるかを認識します。たとえば、SomeClassクラスがMyPropertyという静的プロパティを定義している場合、SomeClassはMyPropertyの値が変更されたときに発生する静的イベントを定義できます。静的イベントは、次のシグネチャのいずれかを使用できます。
public static event EventHandler MyPropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
最初の場合、クラスは、EventArgsをイベントハンドラーに渡すPropertyNameChangedという名前の静的イベントを公開します。 2番目の場合、クラスは、PropertyChangedEventArgsをイベントハンドラーに渡すStaticPropertyChangedという名前の静的イベントを公開します。静的プロパティを実装するクラスは、いずれかの方法を使用してプロパティ変更通知を生成することを選択できます。
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)}"/>
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
プロパティをバインドするには、2つの方法/構文があります。 pがクラスstatic
のMainWindow
プロパティである場合、binding
のtextbox
は次のようになります。
1。
<TextBox Text="{x:Static local:MainWindow.p}" />
2。
<TextBox Text="{Binding Source={x:Static local:MainWindow.p},Mode=OneTime}" />
.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)}" />
私のプロジェクト CalcBinding を見てください。これは、静的プロパティ、ソースプロパティ、数学などを含む複雑な式をPathプロパティ値に記述することを可能にします。だから、あなたはこれを書くことができます:
<TextBox Text="{c:Binding local: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)}"/>
括弧を無視しないでください
これらの答えは、良い慣習に従うことを望んでいるが、OPが何かsimpleを望んでいた場合、すべて良いです。 。基本的な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
のget
/set
機能を介して値を直接変更するために行っているすべてのことを行うことができます。
using System.Windows;
namespace MyWPFApp
{
public partial class MainWindow : Window
{
public MainWindow() { InitializeComponent(); }
private void Button_Click_Poke_Kilroy(object sender, RoutedEventArgs e)
{
textBlock.Text = " \\|||/\r\n" +
" (o o) \r\n" +
"----ooO- (_) -Ooo----";
}
}
}
次に、ボタンをクリックしてそのクリックイベントをトリガーすると、出来上がり!キルロイが表示されます:)