绑定在代码隐藏中定义的对象
我有一些在代码后面实例化的对象,例如,XAML被称为window.xaml,在window.xaml.cs中
protected Dictionary<string, myClass> myDictionary;
我怎样才能将这个对象绑定到,例如,列表视图,只使用XAML标记?
更新:
(这正是我在我的testing代码中):
<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”对吗? 但最终什么也没有显示。
您可以为您的控件,窗体等设置DataContext,如下所示:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
澄清 :
被设置为上面的值的数据上下文应该在任何元素“拥有”后面的代码处完成 – 因此对于Window,您应该将其设置在Window声明中。
我有你的例子使用这个代码:
<Window x:Class="MyClass" Title="{Binding windowname}" DataContext="{Binding RelativeSource={RelativeSource Self}}" Height="470" Width="626">
在这个级别设置的DataContext然后被窗口中的任何元素inheritance(除非你明确地改变它的子元素),所以设置窗口的DataContext后,你应该能够直接绑定到任何控件的CodeBehind 属性在窗口上。
这样做有一个更简单的方法。 您可以为您的窗口或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(); } }
尽pipeGuy的答案是正确的(也许在10个案例中有9个是适合的),值得注意的是,如果你正试图从已经有DataContext设置的控件中进行设置,那么当你设置DataContext回到自己:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
这当然会打破现有的绑定。
如果是这样的话,你应该在你试图绑定的控件上设置RelativeSource,而不是它的父级。
即绑定到UserControl的属性:
Binding Path=PropertyName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}
鉴于目前看到数据绑定到底有多困难,即使您发现设置RelativeSource={RelativeSource Self}
当前工作:)也值得记住这一点。
只是稍微澄清一下: 没有“获取”,“设置”的属性将不能被绑定
就像提问者的情况一样,我正在面对这个案子。 为了使绑定正常工作,我必须有以下几件事情:
//(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>
定义一个转换器:
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>
那么,例如,如果你的字典有一个键是“Name”的条目,那么绑定到它:use
<TextBlock Text="{Binding Dummy, Converter={StaticResource RowIndexConverter}, ConverterParameter=Name}">
使您的财产“windowname”一个DependencyProperty并保持其余相同。
在后面的代码中,将窗口的DataContext设置为字典。 在你的XAML中,你可以写:
<ListView ItemsSource="{Binding}" />
这将把ListView绑定到字典。
对于更复杂的场景,这将是MVVM模式背后技术的一个子集。
一种方法是创build一个ObservableCollection(System.Collections.ObjectModel)并在其中包含字典数据。 那么你应该能够将ObservableCollection绑定到你的ListBox。
在你的XAML中你应该有这样的东西:
<ListBox ItemsSource="{Binding Path=Name_of_your_ObservableCollection" />
我有这个完全相同的问题,但我不是因为我设置一个局部variables…我在一个子窗口,我需要设置一个相对的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">