与MainWindow结合的首选/适当方式

时间:2014-01-23 19:48:36

标签: c# wpf xaml binding

所以我正在构建一个程序,从Microsoft Access数据库中提取表和字段名称,并将它们放入两个不同的Listbox项目中。作为我的绑定测试,我有两个框设置相同(只是一个简单的复制/粘贴,因为我超越自己),我得到表名称绑定成功,但只使用lbTables.DataContext = this;(我试图使用{ {1}}但由于某些原因它不起作用)。 DataContext似乎不会从它上面的窗口继承而来,而我从那里读到的是它应该做什么。

当我开始尝试在XAML中的lbFields上确定DataContext时,我发现了一个奇怪的问题。如果我同时定义和初始化集合,全局(如下所示),lbTables.SetBinding (ListBox.DataContextProperty, new Binding ("MDBtoCSV.MainWindow"));两个ListBox也表现出我对它的期望。

但是如果我在我的代码中初始化集合并使用private ObservableCollection<CheckedListItem<Table>> _listTables = new ObservableCollection<CheckedListItem<Label>> ();,那么只有lbTables填充,而lbFields保持空白。有明确定义DataContext和ItemSource的首选方法或不太脆弱的方法吗?

以下是我的XAML:

                      

lbTables.DataContext = this;

TL; DR:为什么DataContext不会从Window继承?为什么 <ListBox x:Name="lbFields" HorizontalAlignment="Left" Height="70" Margin="10,113,0,0" VerticalAlignment="Top" Width="240" DataContext="{Binding ElementName=appMainWindow, Mode=OneWay}" ItemsSource="{Binding Path=ListTables, Mode=OneWay}"> </ListBox> </Grid> 的行为与XAML版本不同?

修改

ListBox.DataContext = this

2 个答案:

答案 0 :(得分:0)

我强烈建议您查看MVVM pattern example并将其用于WPF和绑定。它使所有这些很多更容易。

我会建议三个ViewModel课程:MainWindowViewModelDatabaseTableViewModelDatabaseTableColumnViewModel。正如您可能想象的那样,它们嵌套在每个相应的属性中,并且具有自己的一些属性,如下所示:

class MainWindowViewModel : ViewModelBase
{
  // Make sure you implement INotifyPropertyChanged and invoke on each property!

  public string Title { get; set; }

  public ObservableCollection<DatabaseTableViewModel> Tables { get; set; }

  public DatabaseTableViewModel SelectedTable { get; set; }
}

class DatabaseTableViewModel : ViewModelBase
{
  public string TableName { get; set; }

  public ObservableCollection<DatabaseTableColumnViewModel> Columns { get; set; }
}

class DatabaseTableColumnTableViewModel : ViewModelBase
{
  public string ColumnName { get; set; }
  public string ColumnType { get; set; }

  public DatabaseTableColumnViewModel SelectedColumn { get; set; }
}

所以你的XAML绑定看起来像这样:

<ListBox ItemsSource="{Binding Path=Tables}"
         SelectedItem="{Binding Path=SelectedTable}">
</ListBox>

<ListBox ItemsSource="{Binding Path=SelectedTable.Columns}" 
         SelectedItem="{Binding Path=SelectedTable.SelectedColumn}">
</ListBox>

你必须对此进行一些工作以使多个选择工作,但这是绑定的一般想法。

您应该将MainWindow.DataContext设置为MainWindowViewModel的实例。

答案 1 :(得分:0)

我正在做的所有事情都表现得很好,我缺少的是MainWindow中的INotifyPropertyChanged。我以前想不出来,但后来我发现this这是我一直在寻找的三个月。