2011-12-01 74 views
0

我有一個包含DataGrid的WPF用戶控件。這個DG包含幾個列,包括狀態的組合框。狀態列表被填充並作爲屬性存儲在我的ViewModel中。在我的WPF DataGrid中的組合框將不會顯示任何項目

我想將StateList屬性綁定到我的Combobox的ItemsSource,但是當我運行窗體並嘗試編輯DG時,組合框不包含任何值,組合框爲空。

這是用戶控件的XAML。

<UserControl x:Class="myproject.View.ucContactView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" d:DesignHeight="475" d:DesignWidth="977"> 
<UserControl.Resources> 
    <ResourceDictionary Source="/Templates/MyResourceDictionary.xaml"/> 
</UserControl.Resources> 
<Grid DataContext="{Binding ViewModel}"> 
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding AddressCollectionViewSource.View}"> 
     <DataGridTemplateColumn Header="State" Width="160"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding StateDescription}"/> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
      <DataGridTemplateColumn.CellEditingTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <ComboBox Name="cboState" 
            SelectedValuePath="StateKey" 
            ItemTemplate="{StaticResource dtStateTemplate}" 
            ItemsSource="{Binding StateList}" 
            SelectedItem="{Binding StateKey, Mode=TwoWay}" 
            Width="100" /> 
        </StackPanel> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellEditingTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid> 
</Grid> 
</UserControl> 

奇怪的是,如果我創建這個用戶控件的另一個組合框具有完全相同的組合框,此組合框按預期工作。

<!-- this works as long as it's not in the DG --> 
<StackPanel Height="126" HorizontalAlignment="Left" Margin="766,275,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200" > 
    <ComboBox Name="cboState2" 
      SelectedValuePath="StateKey" 
      ItemTemplate="{StaticResource dtStateTemplate}" 
      ItemsSource="{Binding StateList}" 
      SelectedItem="{Binding StateKey, Mode=TwoWay}" 
      Width="100" /> 
</StackPanel> 

爲什麼DG中的組合框不顯示StateList屬性中的值?任何爲什麼單獨的組合框工作正常?

+0

爲什麼你不能用'DataGridComboBoxColumn'? –

回答

2

它不工作,因爲你的ComboBox正在尋找StateList作爲t的財產的DataGrid。也就是說,當它需要綁定到ViewModel.StateList時,它試圖綁定到ViewModel.AddressCollectionViewSource.View.StateList。在調試時檢查你的輸出窗口,我敢打賭你會看到一個綁定錯誤Could not find property StateList on object AddressCollectionViewSource (or maybe ICollection)的影響。

試試這個:

<ComboBox Name="cboState2" 
     SelectedValuePath="StateKey" 
     ItemTemplate="{StaticResource dtStateTemplate}" 
     ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
      AncestorType={x:Type DataGrid}}, Path=DataContext.StateList}" 
     SelectedItem="{Binding StateKey, Mode=TwoWay}" 
     Width="100" /> 
1

,如果你的視圖模型是在窗口的屬性,你可以做到這一點

ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=ViewModel.StateList, Mode=OneWay}" 


<Window x:Class="WpfStackOverflowSpielWiese.Window2" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window2" 
     Height="300" 
     Width="300" 
     x:Name="window"> 

    <Grid DataContext="{Binding ElementName=window, Path=ViewModel}"> 

    <DataGrid x:Name="grid" 
       AutoGenerateColumns="False" 
       ItemsSource="{Binding AddressCollectionViewSource, Mode=OneWay}"> 

     <DataGrid.Columns> 
     <DataGridTemplateColumn Header="State" 
           Width="160"> 

      <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding StateKey}" /> 
      </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 

      <DataGridTemplateColumn.CellEditingTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
       <ComboBox Name="cboState" 
          SelectedValuePath="StateKey" 
          ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=ViewModel.StateList, Mode=OneWay}" 
          SelectedItem="{Binding StateKey, Mode=TwoWay}" 
          Width="100" /> 
       </StackPanel> 
      </DataTemplate> 
      </DataGridTemplateColumn.CellEditingTemplate> 

     </DataGridTemplateColumn> 
     </DataGrid.Columns> 

    </DataGrid> 
    </Grid> 
</Window> 


using System.Collections.ObjectModel; 
using System.Windows; 

namespace WpfStackOverflowSpielWiese 
{ 
    /// <summary> 
    /// Interaction logic for Window2.xaml 
    /// </summary> 
    public partial class Window2 : Window 
    { 
    public static readonly DependencyProperty ViewModelProperty = 
     DependencyProperty.Register("ViewModel", typeof(ViewModelClass), typeof(Window2), new PropertyMetadata(default(ViewModelClass))); 

    public ViewModelClass ViewModel { 
     get { return (ViewModelClass)this.GetValue(ViewModelProperty); } 
     set { this.SetValue(ViewModelProperty, value); } 
    } 

    public Window2() { 
     this.InitializeComponent(); 
     this.grid.Items.Clear(); 
     this.ViewModel = new ViewModelClass(); 
    } 
    } 

    public class StateClass : DependencyObject 
    { 
    public static readonly DependencyProperty StateKeyProperty = 
     DependencyProperty.Register("StateKey", typeof(string), typeof(ViewModelClass), new PropertyMetadata(default(string))); 

    public string StateKey { 
     get { return (string)this.GetValue(StateKeyProperty); } 
     set { this.SetValue(StateKeyProperty, value); } 
    } 

    public static readonly DependencyProperty StateProperty = 
     DependencyProperty.Register("State", typeof(string), typeof(StateClass), new PropertyMetadata(default(string))); 

    public string State { 
     get { return (string)this.GetValue(StateProperty); } 
     set { this.SetValue(StateProperty, value); } 
    } 
    } 

    public class ViewModelClass : DependencyObject 
    { 
    public static readonly DependencyProperty StateListProperty = 
     DependencyProperty.Register("StateList", typeof(ObservableCollection<string>), typeof(ViewModelClass), new PropertyMetadata(default(ObservableCollection<string>))); 

    public static readonly DependencyProperty AddressCollectionViewSourceProperty = 
     DependencyProperty.Register("AddressCollectionViewSource", typeof(ObservableCollection<StateClass>), typeof(ViewModelClass), new PropertyMetadata(default(ObservableCollection<StateClass>))); 

    public ObservableCollection<StateClass> AddressCollectionViewSource { 
     get { return (ObservableCollection<StateClass>)this.GetValue(AddressCollectionViewSourceProperty); } 
     set { this.SetValue(AddressCollectionViewSourceProperty, value); } 
    } 

    public ObservableCollection<string> StateList { 
     get { return (ObservableCollection<string>)this.GetValue(StateListProperty); } 
     set { this.SetValue(StateListProperty, value); } 
    } 

    public ViewModelClass() { 
     this.StateList = new ObservableCollection<string>(new[] {"one", "two"}); 
     this.AddressCollectionViewSource = new ObservableCollection<StateClass>(new[] {new StateClass {State = "state", StateKey = "one"}}); 
    } 
    } 
}