我有一个包含DataGrid的WPF用户控件。这个DG包含几个列,包括状态的ComboBox。填充状态列表并将其存储为我的ViewModel中的属性。
我正在尝试将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 :(得分:2)
这不起作用,因为您的ComboBox
正在寻找StateList
作为DataContext
的{{1}}的属性。也就是说,当它需要绑定到DataGrid
时,它会尝试绑定到ViewModel.AddressCollectionViewSource.View.StateList
。在调试时检查输出窗口,我打赌你会看到ViewModel.StateList
的效果的绑定错误。
请改为尝试:
Could not find property StateList on object AddressCollectionViewSource (or maybe ICollection)
答案 1 :(得分:1)
如果您的viewmodel是窗口中的属性,则可以执行此操作
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"}});
}
}
}