代码之家  ›  专栏  ›  技术社区  ›  davidtbernal

WPF数据报单个列中的不同编辑控件

  •  4
  • davidtbernal  · 技术社区  · 14 年前

    我正在开发一个WPF 4.0应用程序,在该应用程序中,我需要生成一个网格,其中包含一个列,该列根据行具有文本框或下拉列表。例子:

    | Name      |  Value                   | Help                                   |
    | PROP1A    | [textbox]                | Description of prop1a                  |
    | Prop2A    | [dropdown v]             | Description of prop2a                  |
    | Prop3A    | [textbox] [x checkbox]   | Description of prop2a                  |
    | Prop4A    | [dropdown v]             | Description of prop2a                  |
    | etc...
    

    其思想是用户有一个需要输入的值表,我们将显示每个值的名称和描述。有些值是需要用文本框输入的数字,而另一些值是文本框加复选框,还有一些值是下拉列表。

    我最初的想法是把它作为我称之为 RowDescriptor 它将指定名称、输入类型和帮助信息(仅为文本),然后使用绑定将集合绑定到数据报。基本上,这些将作为视图模型,并且设置数据报中的值将通过视图模型流向实际模型(就像MVVM应用程序的典型情况一样)。

    不过,当我查看现有的文档时,在任何地方都找不到这样讨论动态更改列类型的方法。我现在倾向于使用一个网格,并手动布局输入(仍然使用绑定,但分别绑定每个元素)。不过,对于我来说,这将是一项更为手动的工作,所以我想知道是否有一种相对简单的方法来实现我的第一个想法。看起来我应该能够使用DataGridTemplateColumn做些什么,但是我对WPF比较陌生,我不确定该怎么做。

    2 回复  |  直到 14 年前
        1
  •  4
  •   Jonathan Allen    14 年前

    您可以使用模板列来完成此操作。

    根据行中的数据,此选项将显示一个或两个文本框。

    CellTemplate正常显示,但在编辑行时将替换为CellEditingTemplate。

    <DataGridTemplateColumn Header="Value" Width="350">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock 
                Text="{Binding EffectiveValue,Mode=OneWay,ValidatesOnDataErrors=True}" 
                ToolTip="{Binding EffectiveValue,Mode=OneWay}"
                TextWrapping="Wrap"
                />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    
        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
    
    
                    <TextBlock  Text="Value" Margin="4"/>
                    <TextBox 
                    Grid.Column="1"
                    Text="{Binding ConfigurationValue,ValidatesOnDataErrors=True}" 
                    ToolTip="{Binding ConfigurationValue}"
                    TextWrapping="Wrap"
                    AcceptsReturn="{Binding DataType, Mode=OneWay, 
                                        Converter={StaticResource ResourceKey=StringMatchBooleanConverter}, ConverterParameter=String}"
                    gui:FocusAttacher.Focus="True" 
                    />
    
                    <TextBlock  Text="Default Value" Grid.Row="1" Margin="4"
                    Visibility="{Binding DefaultConfigurationValue, Converter={StaticResource ResourceKey=NullVisibilityConverter}}"
                            />
                    <TextBox 
                    Grid.Column="1" 
                    Grid.Row="1"
                    Text="{Binding DefaultConfigurationValue, Mode=OneWay }" 
                    ToolTip="{Binding DefaultConfigurationValue, Mode=OneWay}"
                    TextWrapping="Wrap"
                    IsReadOnly="True" 
                    Visibility="{Binding DefaultConfigurationValue, Converter={StaticResource ResourceKey=NullVisibilityConverter}}"
    
                    />
    
                </Grid>
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
    
        2
  •  1
  •   Community nesinervink    7 年前

    我必须在一个带有网格视图的ASP.NET应用程序中完成一次,虽然这是一种不同的技术,但我认为答案是相同的。我要做的只是在每个单元格中添加所有不同类型的控件,但最初不让它们可见。

    然后,您可以重写在将每个项绑定到网格中的行之后激发的任何事件(我也是WPF的新成员,我不确定事件是什么),根据您为该行绑定的对象中所知的任何信息更改单元格中相应控件的可见性,然后填充或绑定该控件到approprIATE值。

    当你需要把值取出来的时候,它确实会变得更有趣,但是我认为我最终会搜索可见的控件,然后根据控件的类型做出决定。我认为这是实现它的唯一方法,因为我从Microsoft使用的每个网格控件似乎都假定您的列永远不需要不同类型的控件。

    我以前问过几乎相同的问题。这里是 the post . 也许它会让你的球滚起来。