【问题标题】:Unable to bind data in combo box in datagrid无法在数据网格的组合框中绑定数据
【发布时间】:2014-07-16 12:22:18
【问题描述】:

我在 WPF 的数据网格中有一个组合框。我无法绑定数据。我使用了下面的代码。

XAML

<DataGrid 
   Name="grdDetails" 
   Width="578" 
   Height="149" 
   ScrollViewer.VerticalScrollBarVisibility="Visible" 
   ScrollViewer.HorizontalScrollBarVisibility="Visible" 
   AutoGenerateColumns="False"  
   MouseRightButtonUp="grdDetails_MouseRightButtonUp" 
   SelectionChanged="grdDetails_SelectionChanged">
   <DataGrid.Columns>
      <DataGridTemplateColumn Width="80" Header="Country">
         <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <TextBlock Text="{Binding Country}" />
            </DataTemplate>
         </DataGridTemplateColumn.CellTemplate>
         <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
               <ComboBox 
                  Name="cbCountry" 
                  ItemsSource="{Binding Path=CountryList}" 
                  SelectedItem="Code" 
                  DisplayMemberPath="Code" 
                  SelectedValuePath="Code"/>
            </DataTemplate>
         </DataGridTemplateColumn.CellEditingTemplate>
      </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

代码隐藏 (C#)

List<CountryDTO> CountryList = new List<CountryDTO>();
CountryList = refController.GetCountryData();  // this brings the list of Country.

请指教。

【问题讨论】:

  • CountryList 定义在哪里?

标签: c# wpf xaml datagrid wpfdatagrid


【解决方案1】:

从您向我们展示的那一小段代码来看,您确实可能遇到很多问题...没有特定的顺序,请检查以下内容:

1) 请确保您的grdDetails DataGrid 将其ItemsSource 属性设置为有效的项目集合,否则DataGrid 中将没有数据...我假设您愚蠢地忽略了它为简洁起见,您的代码示例。

2) 请确保您来自ComboBoxBinding 在范围内。如果您尝试将数据绑定到单个集合,则此 Binding 将不起作用:

<ComboBox Name="cbCountry" ItemsSource="{Binding Path=CountryList}" ... />  

上面的Binding Path 是在ComboBoxItems 的范围内,所以要做到这一点,你需要为每个要显示的数据绑定项添加一个CountryList 集合属性ComboBox。要使这项工作仅使用对象中的一个数据绑定到父 DataContext 属性的集合,您需要使用此 Binding Path

<ComboBox Name="cbCountry" ItemsSource="{Binding Path=DataContext.CountryList, 
    RelativeSource={RelativeSource AncestorType={x:Type YourPrefix:YourView}}}" ... />

3) 在理想情况下,您的数据项应位于ObservableCollection 而不是List。来自 MSDN 上的ObservableCollection&lt;T&gt; Class 页面:

表示一个动态数据集合,在添加、删除项目或刷新整个列表时提供通知。

4) 在 WPF 中使用数据传输对象 (DTO) 作为模型项是不明智的,除非它们实现了INotifyPropertyChanged 接口。即使他们这样做了,几乎总是最好定义您自己的自定义数据类型类,这些类提供在 UI 中编辑和显示所需的所有属性......我们经常需要添加属性只是为了帮助在 UI 中可视化事物。

5) 请确保您已将对象的有效实例设置为您正在使用的WindowUserControlDataContext

6) 请确保您设置为DataContext 的对象实际上有数据进入。

虽然还有您的ComboBox 中可能没有任何数据的其他原因,但不幸的是,我已经没时间了...我已经列出了您的最可能的原因问题,但为了将来参考,也许你可以provide all of the relevant information in your question

【讨论】:

    【解决方案2】:

    使用 MVVM,您需要创建一个如下所示的视图模型类,并在后面的代码中将其实例分配给 Window 的 DataContext 属性。

    那么绑定会是这样的:

    ItemsSource="{Binding Path=CountryList , RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
    

    视图模型类如下所示:

    public class MyViewModel
    {
    
        public ObservableCollection<CountryDTO> CountryList { get; private set; }
    
        public MyViewModel(SomeControler refController)
        {
            CountryList = new ObservableCollection(refController.GetCountryData());
        }
    }
    

    【讨论】:

    • MVVM 不是灵丹妙药,所以这里可能没有必要使用它,但 OservableCollection 很重要!
    【解决方案3】:

    如果在 CodeBedind(而不是 DataContext)中定义 CountryList,您还需要一个 RelativeSource:

    ... ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type YourView}}, Path=CountryList,}" ...
    

    【讨论】:

      【解决方案4】:

      使用 ObservableCollection,而不是列表,那么添加的对象应该可用。更多信息在这里:ObservableCollection<> vs. List<>

      【讨论】:

      • 我没有使用列表,而是使用 DTO 类。
      • 您的 ComboBox.ItemsSource 与 Countrylist 绑定,该列表的类型为 List...如果添加或删除任何对象,GenericLists 不会触发 ChangeNotifications...顺便说一句...您替换整个在新的 List<...> 调用之后列出。最好使用该方法正确初始化它或使用 AddRange。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 2013-03-19
      • 2017-05-17
      • 2011-06-06
      • 2018-05-21
      • 2012-05-15
      • 2012-10-01
      相关资源
      最近更新 更多