当ItemsSource为空时,如何确保我的WPF DataGrid至少显示一行? (可编辑的ComboBox单元格)

时间:2017-08-08 18:39:48

标签: c# wpf mvvm data-binding wpfdatagrid

我有一个DataGrid,允许用户编辑电子设备的属性,例如设备具有哪些输入和输出以用于绘制原理图。可能存在用户正在编辑先前保存的设备的情况 - 在这种情况下,ItemsSource将绑定已经定义的对象的属性。更常见的情况是,用户将从头开始创建新设备,因此ItemsSource将为空启动。在这种情况下,我的DataGrid是完全空白的,我希望它显示一个空行。我的单元格由可编辑的组合框组成。

到目前为止,我无法让DataGrid显示以前定义的ItemsSource,并且当ItemsSource为空时显示空行。

XAML:

<DataGrid Grid.Column="0" Grid.ColumnSpan="2"
              Grid.Row="1" Grid.RowSpan="2"
              ScrollViewer.VerticalScrollBarVisibility="Auto"
              ItemsSource="{Binding InputList}">
        <DataGrid.Columns>

            <DataGridTemplateColumn Header="Label" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox IsEditable="True"
                                    Text="{Binding NewLabel}"
                                    ItemsSource="{Binding Label}"
                                    SelectedValue="{Binding SelectedLabel}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Signal" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox IsEditable="True"
                                    Text="{Binding NewSignal}"
                                    ItemsSource="{Binding Signal}"
                                    SelectedValue="{Binding SelectedSignal}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Terminal" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox IsEditable="True"
                                    Text="{Binding NewTerminal}"
                                    ItemsSource="{Binding Terminal}"
                                    SelectedValue="{Binding SelectedTerminal}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>

    </DataGrid>

绑定如下: InputList - 先前定义的设备的结构{Label,Signal,Terminal}列表。如果这是一个新设备,将在保存时创建新结构。此列表(IOStruct)是我的设备对象的属性。

NewLabel - 用户可以键入新标签(如果它是之前未使用过的标签) 标签 - 以前定义的标签的主列表(使用自动完成功能快速添加)

SelectedLabel - 如果用户选择以前定义的标签,这将用于生成新结构

接下来的两列具有相似的绑定,但适用于Signal类型和终端类型。

运行没有定义InputList的应用程序只给我一个空白的DataGrid,我无法做任何事情。在这种情况下,我希望有一个空行。

非常感谢任何帮助或提示,以使这项工作和改善我的做法!

1 个答案:

答案 0 :(得分:0)

你可以试试这样的......

首先在DataGrid中添加一个额外的列..

 <DataGridTemplateColumn Header="Display Order" Width="96" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding DisplayOrder}" Margin="0" VerticalAlignment="Center" TextAlignment="Right"
                                 HorizontalAlignment="Stretch" x:Name="txtDisplayOrder"  Tag="{Binding}" 
                                 Loaded="txtDisplayOrder_Loaded" MaxLength="1" Background="Transparent" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

DisplayOrder字段应该出现在int ..

类型的ItemsSource中

Loaded事件应该是这样的

    private void txtDisplayOrder_Loaded(object sender, RoutedEventArgs e)
    {
        TextBox txt = sender as TextBox;
        ValidationRuleInteger objDisplayOrder = new ValidationRuleInteger("Display Order", true, false);
        if (txt != null && objDisplayOrder != null)
            txt.GetBindingExpression(TextBox.TextProperty).ParentBinding.ValidationRules.Add(objDisplayOrder);

    }

最后,ValidationRuleInteger类应该如下:

 public class clsValidationRuleInteger :ValidationRule
{
    public string strmsg;
    public bool isRequired;
    public bool? isRegex;
    bool AllowNegativeValues;

    public clsValidationRuleInteger(string strmsg, bool isRequired, bool _AllowNegativeValues)
    {
        this.strmsg = strmsg;
        this.isRequired = isRequired;
        AllowNegativeValues = _AllowNegativeValues;
    }

   public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        throw new NotImplementedException();
    }
}

根据您的要求,这应该可以正常工作......