2008-11-25 23 views
6

我剛剛意識到我一直強制綁定/依賴屬性,並沒有真正從根本上理解這個概念。WPF DependencyProperties

赫雷什依賴屬性:

public string Problem 
{ 
    get { return (string)GetValue(ProblemProperty); } 
    set { SetValue(ProblemProperty, value); } 
} 

public static readonly DependencyProperty ProblemProperty = 
    DependencyProperty.Register(
    "Problem", 
    typeof(string), 
    typeof(TextBox)); 

的XAML是這樣:

<TextBlock Text="{Binding Path=Problem}"/> 

我的Problem屬性手動設置到對象的構造函數值,但它不」 t相應地更新TextBlock。 。 。有任何想法嗎?我試過Mode="OneWay"Mode="TwoWay"關於綁定,它仍然無法正常工作。

我認爲這應該是自動工作?或者我從根本上搞錯了什麼?

謝謝

+0

一切看起來都很好。它必須是你的`DataContext`。你如何設置它? – 2008-11-25 18:05:11

回答

11

你的問題絕對與你的DataContext有關。 {Binding}擴展需要知道您綁定的屬性在哪裏。它看起來的默認位置是元素DataContext,默認情況下它始終設置爲其父元素的DataContext。如果您將DataContext沿着邏輯樹走向父窗口,則DataContext將爲空(因爲您的窗口的DataContext爲空)。因此,你的文本塊上的{Binding}是「將我的Text屬性綁定到我的DataContext的問題屬性,它是空的。」

有幾種方法可以解決這個問題。苡提到並設置你的元素屬性綁定到指向其中的DependencyProperty是這樣定義的窗口:

<TextBlock Text="{Binding Path=Problem,ElementName=_window}" /> 

另一種選擇是設置你的窗口的DataContext的指向本身這樣所有的包含在其內容中的元素將全部具有該窗口的DataContext。

<Window .... 
     DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

現在,只要您需要綁定在窗口中定義(如您的問題依賴屬性)的屬性,那麼你可以這樣做:

<TextBlock Text="{Binding Problem}" /> 
+0

設置窗口datacontext的解決方案本身並不適用於我。 它只適用於將一個或更多級別的元素(第一個網格工作)的元素的datacontext設置爲窗口。 這是預期的嗎? – Erik83 2016-02-26 13:16:42

0

它是一個窗口,這是在設置

public partial class Window1 : Window 
{ 
    public string Problem 
    { 
     get { return (string)GetValue(ProblemProperty); } 
     set { SetValue(ProblemProperty, value); } 
    } 

    public static readonly DependencyProperty ProblemProperty = 
        DependencyProperty.Register(
        "Problem", 
        typeof(string), 
        typeof(Window1)); 


    public Window1() 
    { 
     InitializeComponent(); 

     Problem = "ifowiof"; 
    } 

    public void OnClick(object sender, EventArgs e) 
    { 
     Problem = "behl"; 
    } 

    public void OnCancel(object sender, EventArgs e) 
    { 
     Problem = "eioeopje"; 
    } 
} 

XAML:

<Window x:Class="WpfToolTip.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
     <StackPanel> 
      <Button Click="OnClick" Content="OK" /> 
      <Button Click="OnCancel" Content="Cancel" /> 
      <TextBlock Text="{Binding Path=Problem}" /> 
    </StackPanel> 
</Window> 

它如果我設置RelativeSource就像您在加載時所說的那樣工作,但是如果我手動更改代碼中的Problem屬性(即。通過一個按鈕點擊)它從不更新TextBlock與新的價值。

+0

你有沒有找到答案?我有類似的問題。當您設置問題屬性時,綁定似乎會丟失。我不確定以這種方式更新值的正確程序是什麼。 – 2008-12-19 09:18:25

2

您可以在這裏使用ElementName綁定,元素將是Window本身。

<Window x:Class="WpfToolTip.Window1" 
x:Name="_window" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <StackPanel> 
     <Button Click="OnClick" Content="OK" /> 
     <Button Click="OnCancel" Content="Cancel" /> 
     <TextBlock Text="{Binding Path=Problem,ElementName=_window}" /> 
</StackPanel> 

0

在你的代碼註冊依賴屬性的類文本框(報價的最後一行)。

公共靜態只讀的DependencyProperty ProblemProperty =
DependencyProperty.Register(
「問題」,
typeof運算(字符串),
typeof運算(文本框));

因此,您可以爲ProblemProperty設置僅用於文本框的值,但我無法在任何代碼片段中找到任何文本框。 您應該從樣本中註冊您的依賴項屬性,該值將被賦值給哪個類型,正確的選擇對我來說並不明顯。 您可以像Micah那樣將其定義爲窗口的DP,然後在您的實例化窗口上設置該屬性。或者你可以將它定義到窗口內的任何命名的依賴對象,即用名稱= m_ContentElement一些對象,然後設置您的結合
{Binding ElementName=m_ContentElement, Path=Problem}
或更短:
{Binding Problem, ElementName=m_ContentElement}

0

有兩種方式來了解原因你描述的問題。

起初 - 你應該嘗試設置屬性更改處理程序(在依賴項屬性聲明中),並將斷點放在那裏。你會看到你的財產是否正在改變。

第二個 - 你應該檢查依賴項屬性所有者的類型。

您能否展示完整的xaml和代碼隱藏?

2

嘗試typeof(object)而不是typeof(string)

相關問題