从数据网格提取数据到绑定组合框

本文关键字:数据 绑定 组合 提取 数据网 网格 | 更新日期: 2023-09-27 18:13:06

我要做的是将字符串从我的DataGrid中的特定列中取出,并在组合框中显示该字符串。文本属性。我使用以下代码:

var dataString = ((DataRowView)dgvMain.SelectedItem).Row["Column"].ToString();

我在这上面放置了一个断点,看看它在拉什么,它是正确的字符串,包含在组合框中的一个项目,但每当我试图通过组合框设置它。文本时,组合框为空。然而,我已经将我的组合框设置为isEditable = True和ReadOnly = True,这个方法可以工作,但是在集合中选择一个项目将显示System.Data。DataRowView,由于组合框被绑定到我的数据表。我也将XAML添加到我的组合框中:

<ComboBox x:Name="cboAlarmType" HorizontalAlignment="Left" Margin="138,256,0,0" VerticalAlignment="Top" Width="320" TabIndex="5"
              BorderBrush="Black" Background="White" ItemsSource="{Binding}" DisplayMemberPath="AlarmName" SelectedValuePath="AlarmName" 
              SelectedValue="{Binding Row.Column, ElementName=dgvMain}"/>

此方法适用于文本框和复选框,但似乎还没有找到它的组合框。任何指导将不胜感激!:)

从数据网格提取数据到绑定组合框

在我看来,ComboBoxDataContext必须是您用于填充DataGridDataTable,因为ItemsSource="{Binding}"。我将假设DataGrid也是DataContext,并且您的目标是让ComboBox选择反映DataGrid中所选的行。

<DataGrid
    x:Name="dgvMain"
    ItemsSource="{Binding}"
    />
<ComboBox
    ItemsSource="{Binding}"
    DisplayMemberPath="Column"
    SelectedValuePath="Column"
    SelectedValue="{Binding SelectedItem.Row[Column], ElementName=dgvMain}"
    />

如果你想让选择的改变是双向的——所以改变ComboBox的选择会改变DataGrid的选择——这很简单:

<DataGrid
    x:Name="dgvMain"
    ItemsSource="{Binding}"
    SelectedValuePath="Column"
    SelectedValue="{Binding SelectedValue, ElementName=ColumnComboBox}"
    />
<ComboBox
    x:Name="ColumnComboBox"
    ItemsSource="{Binding}"
    DisplayMemberPath="Column"
    SelectedValuePath="Column"
    SelectedValue="{Binding SelectedItem.Row[Column], ElementName=dgvMain}"
    />

这里有一个更干净的方法来做整个事情:首先,用c#编写一个视图模型类。

public class ViewModelbase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
public class MyViewModel : ViewModelbase
{
    public MyViewModel()
    {
        //  I populated my DataTable with "Row 1", "Row 2", etc.
        //  Naturally you'd use a value from your own data. 
        SelectedColumnValue = "Row 2";
    }
    #region SelectedColumnValue Property
    private String _selectedColumnValue = default(String);
    public String SelectedColumnValue
    {
        get { return _selectedColumnValue; }
        set
        {
            if (value != _selectedColumnValue)
            {
                _selectedColumnValue = value;
                OnPropertyChanged();
            }
        }
    }
    #endregion SelectedColumnValue Property
    public DataTable Data { get; protected set; }
}

然后使用SelectedColumnValue属性来跟踪两个控件的"Column"的选定值。默认情况下,两个控件的SelectedValue属性绑定将是双向的,因为框架的东西使它成为那样(这是如何解释的?)。因此,如果您以编程方式更改SelectedColumnValue,控件将更新,如果用户更改网格选择,则viewmodel属性将更新,这将反过来更新ComboBox——反之亦然。

<DataGrid
    ItemsSource="{Binding Data}"
    SelectedValuePath="Column"
    SelectedValue="{Binding SelectedColumnValue}"
    />
<ComboBox
    ItemsSource="{Binding Data}"
    DisplayMemberPath="Column"
    SelectedValuePath="Column"
    SelectedValue="{Binding SelectedColumnValue}"
    />
<ComboBox
    ItemsSource="{Binding Data}"
    DisplayMemberPath="ShoeSize"
    SelectedValuePath="Column"
    SelectedValue="{Binding SelectedColumnValue}"
    />

另一个问题是DisplayMemberPathSelectedValuePath不需要相同。假设我们在Data中有一个"ShoeSize"列,我们希望在另一个ComboBox中显示这些值。我们可以这样做。我们仍然使用Column作为Data中行的唯一标识符,但是我们可以告诉ComboBox显示其他列。