2009-06-01 161 views
143

我很難將簡單的靜態字符串屬性綁定到文本框。綁定到靜態屬性

下面是與靜態屬性的類:

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> 

一切編譯,但在運行時,我收到以下例外情況:

無法轉換屬性中的值 'Source't o類型爲 'System.Windows.Markup.StaticExtension'的對象。 錯誤在 標記文件 'BurnDisk;組件/ selectversionpagefunction.xaml' 對象 'System.Windows.Data.Binding' 線57的位置29.

任何想法,我做錯了嗎?

回答

144

如果綁定需要是雙向的,你必須提供一個路徑。如果類不是靜態的,那麼對靜態屬性執行雙向綁定是個竅門:在資源中聲明類的虛擬實例,並將其用作綁定的源。

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

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

你不能綁定到這樣的靜態。由於沒有涉及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}"/> 
+2

真的嗎?我已經能夠綁定到與我的示例非常相似的靜態Int32.MaxValue: 這是因爲它是單向的嗎? – 2009-06-01 19:36:19

+2

是的,任何雙向綁定都需要一個綁定的Path屬性值Source必須是一個包含Path指定屬性的對象 指定OneWay將刪除該限制。 – 2009-06-01 21:30:29

+0

此外,對於後期更新抱歉,但我更新了上述答案與示例。 – 2009-06-01 21:37:00

34

在.NET 4.5有可能綁定到靜態屬性,read more

您可以使用靜態屬性作爲數據綁定的源。如果引發了一個 靜態事件,則數據綁定引擎會識別該屬性的值何時更改。例如,如果類SomeClass定義了名爲MyProperty的靜態屬性 ,則SomeClass可以定義在My​​Property的值更改時引發的靜態事件 。靜態事件 可以使用下面的簽名:

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

注意的是,在第一種情況下,該類暴露了EventArgs的傳遞到事件處理程序命名 PropertyNameChanged一個靜態的事件。 在第二種情況下,該類公開一個名爲 的StaticPropertyChanged,它將PropertyChangedEventArgs傳遞給 事件處理程序。實現靜態屬性的類可以選擇 以使用任一方法來引發屬性更改通知。

7

您可以使用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

如果您正在使用本地資源,你可以把它們稱爲如下:

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

可能有兩種方法/語法綁定static屬性。如果p是類MainWindow,則static財產bindingtextbox將是:

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

2.

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

看我的項目CalcBinding,它提供給你在Path屬性值中編寫複雜表達式,包括靜態屬性,源屬性,Math等。所以,你可以這樣寫:

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

Goodluck!

2

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