无法看到绑定到ObservableCollection

时间:2017-01-25 14:30:57

标签: c# wpf xaml mvvm datagrid

我正在使用具有手动定义列的DataGrid处理WPF应用程序。 在该DataGrid中,用户应能够输入包括下限(小数值)和比较符号("<"或"< =")的数据。 / p>

DataGrid本身绑定到名为StepDataSource的ObservableCollection:

    /// <summary>
    /// Gets or sets the data of the stepfunction.
    /// </summary>
    public ObservableCollection<StepData> StepDataSource
    {
        get { return stepdataSource; }
        set
        {
            stepdataSource = value;
            RaisePropertyChanged("StepDataSource");
        }
    }

类StepData(不属于viewmodel)包含以下属性:

    /// <summary>
    /// Gets or sets the lower bound.
    /// </summary>
    public double LowerBound { get; set; }

    /// <summary>
    /// Gets or sets the assigned value.
    /// </summary>
    public double StepValue { get; set; }

    /// <summary>
    /// Gets or sets the lower comparer.
    /// </summary>
    public ArithmeticSignData LowerComparer2 { get; set; }

在ComboBox中选择的项目需要最后一个属性LowerComparer2。

DataGrid中的一个列是DataGridComboBoxColumn,它绑定到我的viewmodel中的另一个ObservableCollection:

    public ObservableCollection<ArithmeticSignData> LowerComparers2 { get; set; }

类ArithmeticSignData包含ComboBox将使用的键和值的属性。

public class ArithmeticSignData
{
    /// <summary>
    /// The constructor.
    /// </summary>
    /// <param name="key">The key.</param>
    /// <param name="value">The value.</param>
    public ArithmeticSignData(string key, string value)
    {
        ArithmeticSignKey = key;
        ArithmeticSignValue = value;
    }

    public string ArithmeticSignKey { get; set; }

    public string ArithmeticSignValue { get; set; }

}

在视图模型中填写该集合:

        LowerComparers2 = new ObservableCollection<ArithmeticSignData>();
        LowerComparers2.Add(new ArithmeticSignData("1", "<"));
        LowerComparers2.Add(new ArithmeticSignData("2", "<="));

然后我在DataGrid中定义了这样的列:

    <DataGrid x:Name="grd_stepdata"
              Grid.Row="0"
              Grid.Column="0"
              Margin="5"
              AutoGenerateColumns="False"
              CanUserAddRows="True"
              CanUserDeleteRows="True"
              SelectionUnit="FullRow"
              ItemsSource="{Binding StepDataSource, NotifyOnSourceUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <DataGrid.Columns>
            <DataGridComboBoxColumn x:Name="col_LowerComparer2"
                                    SelectedItemBinding="{Binding LowerComparer2, NotifyOnSourceUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    DisplayMemberPath="ArithmeticSignValue"
                                    Header="LowComp"/>
        </DataGrid.Columns>
    </DataGrid>

通过本论坛的一些文章,我了解到必须在代码隐藏中设置ItemsSource:

col_LowerComparer2.ItemsSource = vm.LowerComparers2;

当我启动应用程序并选择一个项目时,我可以在我的viewmodel-property LowerComparer2中看到具有正确键和值的所选项目。 但遗憾的是,在我启动应用程序后,我无法从列中的viewmodel中看到现有数据。

我忘记了一个或多个属性吗?

1 个答案:

答案 0 :(得分:2)

试试这个:

<DataGridComboBoxColumn x:Name="col_LowerComparer2"
                                    SelectedItemBinding="{Binding LowerComparer2, NotifyOnSourceUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    DisplayMemberPath="ArithmeticSignValue"
                                    Header="LowComp">
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding Path=DataContext.LowerComparers2, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding Path=DataContext.LowerComparers2, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

另请注意,StepData对象的LowerComparer2属性返回的对象必须存在于MainViewModelClass的LowerComparers2集合中才能选择项目。这意味着您无法将此属性设置为 new ArithmeticSignData对象。您应该将其设置为已添加到LowerComparers2集合的任何ArithmeticSignData个对象:

using System.Linq;
...

public MainWindow()
{
    // The window components are initialized.
    InitializeComponent();

    // DataContext gets the viewmodel.
    DataContext = vm;

    vm.StepDataSource.Add(new StepData("<", 0, 0, vm.LowerComparers2.FirstOrDefault(x => x.ArithmeticSignKey == "1")));
    vm.StepDataSource.Add(new StepData("<=", 0.1, 0.8, vm.LowerComparers2.FirstOrDefault(x => x.ArithmeticSignKey == "2")));
    vm.StepDataSource.Add(new StepData("<", 0.2, 1.2, vm.LowerComparers2.FirstOrDefault(x => x.ArithmeticSignKey == "1")));
    vm.StepDataSource.Add(new StepData("<=", 0.3, 1.4, vm.LowerComparers2.FirstOrDefault(x => x.ArithmeticSignKey == "2")));
    ChartDataRefresh();

    ...
}