2009-11-10 90 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