2012-01-23 28 views
2

我是新来WPF和整个数据绑定的东西。我读了几篇文章,对于如何将数据绑定到UI元素我感到很困惑。了解DataBinding

我看到一个帖子做这种方式:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Name="myWindow"> 
    <Grid> 
     <TextBox Text="{Binding Path=Speed, ElementName=myWindow}" /> 
    </Grid> 
</Window> 

这是假设Speed是在代码隐藏文件中定义的属性/成员。其他一些人使用静态资源命名绑定,并引用该名称和其他名为DataContext的名称以用于绑定。现在,因为我对WPF的数据绑定很陌生,所以我很不确定是否存在任何有关使用哪种数据绑定的最佳实践方法。

基本上我想知道为什么必须有几个class-property被定义为底层viewmodel的一种连接器,我虽然这个东西更“动态”。

我只瞄准了XAML文件,而不需要在文件后面的* .xaml.cs代码中添加任何东西。例如:我有一个名为MainWindowViewModel的类(它将代表我的ViewModel)拥有ObservableCollection<string>类型的成员,并且我想将ListBox(在我的视图中)绑定到此集合。到目前为止,我得到这个工作的唯一方法是使用第一种情况,即ElementName,我必须为视图类添加一个属性作为一种连接器。就像这样:

MainWindow.xaml:

<Window x:Class="Sample.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Name="MW" Title="MainWindow" Height="419" Width="463"> 
    <Grid> 
     <ListBox ItemsSource="{Binding ElementName=MW, Path=ListerResultConnector}" /> 
    </Grid> 
</Window> 

MainWindow.xaml.cs:

private ObservableCollection<string> mListerResultData = MainWindowViewModel.Instance.RetrievalStringResults; 
public ObservableCollection<string> ListerResultConnector 
{ 
    get { return mListerResultData; } 
} 

我的问题是,如果因为使用存在将数据绑定到我UI的明智之选作为代码隐藏文件中的“连接器”属性。

+0

请看看这些相关的问题: - http://stackoverflow.com/questions/7472/wpf-databinding http://stackoverflow.com/questions/6807006/c-sharp-databinding-tutorial –

回答

2

您的ViewModel应该设置为视图的DataContext。那么在代码隐藏中你不需要任何“进一步的连接器”。绑定实际上是指DataContext,如果你没有设置它,它仍然是'this',它对应于你的代码隐藏文件(这只是你的视图的一部分)。

此外,看一看:WPF Apps With The Model-View-ViewModel Design Pattern

你应该得到的WPF和它的第一个绑定的基础知识,但一旦你了解这些,我建议看Caliburn Micro其以公约为基础的绑定,事件处理等功能这使您的代码更清洁。

1

您的{Binding ElementName=MW表示您绑定到窗口本身,因此您的DataContext是窗口,并且您实现的任何属性都需要在该窗口中定义(在您的代码中 - 您的“连接器”)。

您需要删除ElementName=MW位并将您的ViewModel指定为DataContext,以便您可以直接绑定到其属性。你如何做到这一点取决于你是否用“视图模型一”或“检视首个”

在查看前,您可以手动在创建视图分配的DataContext的视图代码。

在视图模型首先,创建于XAML一个DataTemplate是关系你查看一个特定的视图模型。我认为ViewModel首先更常见。 Darjan发布的链接应该可以帮助你理解差异。

+1

谢谢为了您的评论,事实上,在所有帖子的共同帮助下,我按照自己想要的方式工作。你让我意识到我将决定如何使用MVVM模式,目前我使用的是“View-First”,因为它更容易实现,但我很难考虑设置一些xaml模板在将我的视图模型连接到视图时更具动态性。非常感谢! – inva

1

您应该使用单独的ViewModel类(WindowViewModel),它表示您的窗口的数据上下文(Window.DataContext)。

我发现使用MVVM Light toolkit和继网站上的一些视频帮助我填补了空白。在开始之前花些时间学习它,它将开始沉入其中。IoC containers也与MVVM + WPF混合用于目录管理&视图模型的生命周期管理和改进的设计时体验(可混合性)。

工具箱不是必需的,有时候会学习模式。一旦你理解了,你应该利用一个工具包来加速开发过程。这是一个comparison of various MVVM toolkits

1

绑定通常有两个部分:一个源对象和属性名

当您在绑定指定ElementName,您正在设置源对象。指定绑定源对象的其他方法包括RelativeSourceSource属性。您也可以不定义绑定的源对象,在这种情况下,它将使用当前对象的任何DataContext。源对象可以是在WPF的VisualTree中找到的UI元素,也可以是控件中的类对象DataContext

当您指定Path时,您要告诉绑定使用哪个Property。您也可以将此属性留空以绑定到当前对象的DataContext

DataContext是存储在控件后面的数据对象。这通常是ModelViewModel(如果使用MVVM),但它也可以是几乎任何对象,例如UI元素。

在您的例子

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Name="myWindow"> 
    <Grid> 
     <TextBox Text="{Binding Path=Speed, ElementName=myWindow}" /> 
    </Grid> 
</Window> 

你说的是结合它的源对象是UI元素在名为myWindow可视化树和属性被称为Speed。由于名为myWindow的对象的类型为Window,因此仅当您的Window类实际上具有名为Speed的属性时,此绑定才有效。

这里有很多答案,建议您切换到使用MVVM设计模式,我同意您应该尝试使用MVVM,如果您使用WPF。由于您将应用程序逻辑与UI分离,因此它使编码变得更加简单。如果你有兴趣,我有一个simple MVVM example posted on my blog,它解释了该设计模式的基础知识。

1

做最简单的方法将是:

<Window x:Class="WpfApplication4.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ctrl="clr-namespace:WpfApplication4" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <ctrl:MainWindowViewModel x:Key="mym" /> 
</Window.Resources> 
<Grid DataContext="{Binding Source={StaticResource mym}}"> 
    <ListBox ItemsSource="{Binding Path=MyListProp}" /> 
</Grid> 

上面的例子执行以下操作:

  1. 创建视图模型的新对象的资源为你的窗口
  2. 将视图模型指定为DataContext作为窗口(根网格更精确)
  3. 将列表框绑定到您的ViewModel ObservableCollection属性MyListProp。

试着熟悉绑定类的属性,通过使用msdn库来充分理解本示例。 另外WPF 4释放 - Adam Nathan是一个wpf初学者的好资源。第13章 - 数据绑定应涵盖您可能想要了解绑定的所有信息。

1

是的,绑定是没有什么,如果不混淆。

This example from msdn可能是有帮助的。请注意0​​是如何在Window“级别”声明的 - 在这种情况下,它是一个复杂/复合对象,因此Window子元素的{Binding}声明隐含地相对于“父级”DataContext

我们得到的主要好处是,当DataContext设置为给定对象时,所有“子元素”数据绑定都会自动保持同步。我们可以通过使用这种模式在UI控制结构的任何/多个级别上控制这种同步。

收集罩

下结合的底线是您的收藏必须实现IList最低限度。许多.NET集合类都是“绑定就绪”的。

下面是来自msnd doc on ObservableCollection报价:

之前实现自己的收藏,可以考虑使用的ObservableCollection或现有的集合类,如List,收集和的BindingList,在许多其他之中的一个。如果您有一个高级场景并希望实现自己的集合,请考虑使用IList,它提供了可以通过索引单独访问的非泛型对象集合。实施IList可以提供数据绑定引擎的最佳性能。

最后,IBinding list vs IList是双向绑定所必需的。