2009-11-10 117 views
70

我有一個代碼實例化的背後,例如某個對象時,XAML被稱爲window.xaml和Binding對象代碼隱藏

protected Dictionary<string, myClass> myDictionary; 

我如何可以將綁定在window.xaml.cs內這個對象,例如,一個列表視圖,只使用XAML標記?

更新:

(這正是我在我的測試代碼):

<Window x:Class="QuizBee.Host.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="{Binding windowname}" Height="300" Width="300" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
    </Grid> 
</Window> 

而在代碼隱藏

public partial class Window1 : Window 
{ 
    public const string windowname = "ABCDEFG"; 

    public Window1() 
    { 
     InitializeComponent(); 
    } 
} 

假設標題應成爲 「ABCDEFG」 的權利?但最終什麼也沒有顯示。

+1

奇怪的是,如果我改變窗口的財產分配的順序,它不工作。如果我設置「標題」屬性,然後是「DataContext」屬性,綁定不會發生。任何人都可以解釋嗎? Ramesh 2011-10-05 08:23:13

回答

82

您可以設置的DataContext你的控制,形式等,像這樣:

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

澄清

被設置爲上述值的數據上下文應該在任何元素「擁有」後面的代碼時完成 - 因此對於Window,您應該將其設置爲窗口聲明。

我有你的榜樣,此代碼的工作:設置後

<Window x:Class="MyClass" 
    Title="{Binding windowname}" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    Height="470" Width="626"> 

DataContext的設置在這個水平,然後通過在窗口中的任何元素(除非你明確地改變它的子元素)繼承,所以在DataContext的窗口,你應該能夠只是做直接從窗口上的任何控件綁定到代碼隱藏性能

+0

」Self 「這裏是指控制,而不是整個窗口類,是嗎? – xandy 2009-11-10 03:04:31

+0

奇怪的是,以下是我有的代碼,它不能按預期工作: 公共部分類Window1:窗口 { public const windowname =「ABCDEFG」; public Window1() { InitializeComponent(); } } <窗口x:類= 「QuizBee.Host.Window1」 的xmlns = 「http://schemas.microsoft.com/winfx/2006/xaml/presentation」 的xmlns:X =「HTTP:// schemas.microsoft.com/winfx/2006/xaml「 Title =」{Binding windowname}「Height =」300「Width =」300「 DataContext =」{Binding RelativeSource = {RelativeSource Self}}「> – xandy 2009-11-10 09:04:38

+8

哦,現在沒關係,我將windowname改爲屬性而不是純公共變量,現在可以顯示!謝謝! – xandy 2009-11-10 09:10:21

0

在您的代碼背後,將窗口的DataContext設置爲字典。在您的XAML中,您可以編寫:

<ListView ItemsSource="{Binding}" /> 

這會將ListView綁定到字典。

對於更復雜的場景,這將是MVVM模式背後技術的子集。

0

一種方法是創建一個ObservableCollection(System.Collections.ObjectModel)並在其中存儲字典數據。那麼你應該能夠將ObservableCollection綁定到你的ListBox。

在XAML中,你應該有這樣的事情:

<ListBox ItemsSource="{Binding Path=Name_of_your_ObservableCollection" /> 
1

定義轉換器:

public class RowIndexConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
          object parameter, CultureInfo culture) 
    { 
     var row = (IDictionary<string, object>) value; 
     var key = (string) parameter; 
     return row.Keys.Contains(key) ? row[ key ] : null; 
    } 

    public object ConvertBack(object value, Type targetType, 
           object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

綁定到一個詞典的自定義的定義。有很多我已經省略的覆蓋,但是索引器是重要的,因爲它在值更改時發出屬性已更改的事件。這對於源目標綁定是必需的。

public class BindableRow : INotifyPropertyChanged, IDictionary<string, object> 
{ 
    private Dictionary<string, object> _data = new Dictionary<string, object>(); 

    public object Dummy // Provides a dummy property for the column to bind to 
    { 
     get 
     { 
      return this; 
     } 
     set 
     { 
      var o = value; 
     } 
    } 


    public object this[ string index ] 
    { 
     get 
     { 
      return _data[ index ]; 
     } 
     set 
     { 
      _data[ index ] = value; 
      InvokePropertyChanged(new PropertyChangedEventArgs("Dummy")); // Trigger update 
     } 
    } 


} 

在您的.xaml文件中使用此轉換器。第一參考吧:

<UserControl.Resources> 
    <ViewModelHelpers:RowIndexConverter x:Key="RowIndexConverter"/> 
</UserControl.Resources> 

然後,例如,如果你的字典裏的條目,其中關鍵是「名」,然後綁定到它:使用

<TextBlock Text="{Binding Dummy, Converter={StaticResource RowIndexConverter}, ConverterParameter=Name}"> 
1

讓你的財產「windowname」一個DependencyProperty並保持其餘相同。

22

雖然蓋伊的答案是正確的(可能適合10的9個案件),值得注意的是,如果你正試圖從已經擁有的DataContext進一步設置堆棧控制做到這一點,你就會復位本當您設置的DataContext回自己:

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

這當然會再突破現有的綁定。

如果是這種情況,您應該在您嘗試綁定的控件上設置RelativeSource,而不是其父項。

即綁定到用戶控件的屬性:

Binding Path=PropertyName, 
     RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}} 

考慮是多麼困難可能是目前看到發生了什麼事情與數據綁定,這是值得銘記這一點,即使你發現設置RelativeSource={RelativeSource Self}當前工作:)

+1

Silverlight 4不支持FindAncestor。但是,您需要這樣做,您可以按照本網站上的描述來實現FindAncestor。 [http://blog.thekieners.com/2010/09/08/relativesource-binding-with-findancestor-mode-in-silverlight/](http://blog.thekieners.com/2010/09/08/ relativesource-binding-with-findancestor-mode-in-silverlight /) – ShawnFeatherly 2011-05-24 18:42:08

107

這樣做有一個更簡單的方法。您可以爲您的窗口或UserControl分配一個名稱,然後通過ElementName進行綁定。

Window1.xaml

<Window x:Class="QuizBee.Host.Window1" 
     x:Name="Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <ListView ItemsSource="{Binding ElementName=Window1, Path=myDictionary}" /> 
</Window> 

Window1.xaml.cs

public partial class Window1:Window 
{ 
    // the property must be public, and it must have a getter & setter 
    public Dictionary<string, myClass> myDictionary { get; set; } 

    public Window1() 
    { 
     // define the dictionary items in the constructor 
     // do the defining BEFORE the InitializeComponent(); 

     myDictionary = new Dictionary<string, myClass>() 
     { 
      {"item 1", new myClass(1)}, 
      {"item 2", new myClass(2)}, 
      {"item 3", new myClass(3)}, 
      {"item 4", new myClass(4)}, 
      {"item 5", new myClass(5)}, 
     }; 

     InitializeComponent(); 
    } 
} 
+0

這正是我正在尋找的......謝謝。 – 2012-02-15 18:23:56

+24

用於設置綁定屬性的+1 BEFORE InitializeComponent() – 2012-05-03 18:07:59

+2

我必須更改x:Name(編譯器錯誤CS0542)。然後ElementName需要相應地改變。 – 2016-12-02 14:21:13

0

我有此相同的問題,但我的是不是因爲我設置一個局部變量。 ..我在一個孩子窗口,我需要設置一個相關的DataContext,我剛剛添加到窗口XAML。

<Window x:Class="Log4Net_Viewer.LogItemWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    Title="LogItemWindow" Height="397" Width="572"> 
4

只是多一點澄清:沒有「得到」,「設置」將不能在出現屬性綁定

我面對就像提問者的情況下的情況。我必須擁有以下的東西,以便綁定正常工作:

//(1) Declare a property with 'get','set' in code behind 
public partial class my_class:Window { 
    public String My_Property { get; set; } 
    ... 

//(2) Initialise the property in constructor of code behind 
public partial class my_class:Window { 
    ... 
    public my_class() { 
    My_Property = "my-string-value"; 
    InitializeComponent(); 
    } 

//(3) Set data context in window xaml and specify a binding 
<Window ... 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <TextBlock Text="{Binding My_Property}"/> 
</Window> 
+3

你怎麼能有一個財產沒有'得到'和'設置'?這不是一個領域,而不是一個財產? – kjbartel 2014-10-21 02:58:18