【问题标题】:How to display a DataGrid property with combo box/drop down list that varies according to input of another text box property如何使用组合框/下拉列表显示 DataGrid 属性,该组合框/下拉列表根据另一个文本框属性的输入而变化
【发布时间】:2020-05-01 06:26:49
【问题描述】:

我有一个 DataGrid,它绑定到如下所示的具有各种属性的列表。我有 2 个要求正在努力解决。

<DataGrid  ItemsSource="{Binding Path=VariedObjectList}" 
AutoGeneratingColumn="OnAutoGeneratingColumn" x:Name="dataGridView"
                          SelectionMode="Single" AutoGenerateColumns="true" CanUserAddRows="true"  CanUserDeleteRows="true />
  1. 对于文本框property1中的特定值,property2中显示的项目列表应该动态变化。所以,例如,在这里 如果 'Value' 的值为 2,则 'ValueRange' 应显示一个下拉列表,其中项目为“2-5”和“5.81-6.6”作为列表项,如果值为 8,则列表更改为 => 7.9-8.8; 8.81-11.2 等等,如下图所示。

我怎样才能做到这一点?我想像上面的 xaml 一样保持与整个集合本身的绑定。

 public class VariedObjectList
{
    public Modes ModeType { get; set; }
    public int Value{ get; set; }
    public <dataType??> ValueRange { get; set; } // not sure what should be the type for ValueRange

}
public enum Mode
    {
        ModeSlow = 0,
        ModeFast = 1,
        ModeNeutral = 2,
        ModeNone = 3
    }


  1. 如果我的“ModeType”属性是“ModeSlow”或“ModeFast”,则“ValueRange”需要是一个下拉列表。如果 ModeType 是“ModeNeutral”,那么 ValueRange 必须接受一个文本框。我如何做到这一点?

我按照 Keith 的建议修改了代码,虽然我的大部分更改都有效,但我在以下方面存在问题

(i)我无法让组合框可编辑工作。当我输入时它具有价值,但是一旦我的焦点离开该字段,文本就会消失,并且对于输入的文本,“SelectedValueRange”永远不会发生绑定。但是当有一个列表并且我从列表中选择任何值时,它会绑定到“SelectedValueRange”,但不适用于文本输入。

(ii)ModeType 是枚举,默认情况下输入新行时,我希望它显示“ModeSlow”但它为空。此外,如果我更新一行,所有先前的行也会更新为最新的值。它的行为很奇怪,但我知道我遗漏了一些东西。

public class VariedObjectList : INotifyPropertyChanged
{
    public Mode ModeType { get; set; } = Mode.ModeSlow;
    private int val;
    public int Value {
            get { return val; }
            set
            {
                val = value;

                OnPropertyChanged("Value");
                SetValueRangeList();
            }
        }
    public List<strings> ValueRange { get; set; } 
    public string SelectedValueRange {get; set;}

}

下面是更新的xaml

我正在为枚举设置 ObjectDataProvider

<Window.Resources>
        <ObjectDataProvider x:Key="EnumProvider" MethodName="GetValues"
                            ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Modes"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
</Window.Resources >

<DataGrid x:Name="dataGridView" Grid.Row="0" DataGridCell.Selected="DataGridGotFocus" ItemsSource="{Binding VariedObjectList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" 
                               CanUserDeleteRows="true"  SelectionMode="Single" CanUserAddRows="True" VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">

                    <DataGrid.Columns>
                        <DataGridTemplateColumn  Header=" ModeType " >
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox ItemsSource="{Binding Source={StaticResource EnumProvider}}"
                                              SelectedItem="{Binding Path= ModeType 
, UpdateSourceTrigger=LostFocus, Mode=TwoWay}" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Header="Value" Binding="{Binding Value, UpdateSourceTrigger=LostFocus}"/>
                        <DataGridTemplateColumn  Header="ValueRange" >
                            <DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <ComboBox IsEditable="True" SelectedValue="{Binding SelectedValueRange, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Path= ValueRange }" /> 
                                </DataTemplate>
                            </DataGridTemplateColumn.CellEditingTemplate>
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding SelectedValueRange, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>

                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>


有人可以指出我在示例代码中缺少什么吗?谢谢。

【问题讨论】:

  • 这可能吗?我看到这么多观点,但没有回应。请让我知道是否需要更多信息。

标签: c# wpf drop-down-menu datagrid itemsource


【解决方案1】:

让我们从VariedObjectList 类开始:

  • 由于 ValueRange 将发生变化,而您希望 UI 随之更新,VariedObjectList 将不得不实现 INotifyPropertyChanged Interface

  • ValueRange 的类型可以是int 的任何泛型集合。我建议将该属性声明为IList&lt;int&gt;,因为如果需要,它可以为您提供大量空间来使用不同的集合。

  • ModeType.set 中,连同提升PropertyChanged,您需要创建或检索要为该Mode 显示的值列表,然后将该列表分配给ValueRange

现在是DataGrid

如果您想根据ModeType 更改ValueRange 列的行为,您将不得不放弃AutoGenerateColumns="true" 相反,您将明确定义&lt;DataGrid.Columns&gt; 标记之间的列。

我会推荐DataGridTemplateColumn 用于ValueRange 列。 CellEditingTemplate 将包含 ComboBoxItemsSource={Binding ValueRange}。您可以将Style 应用于ComboBox,它会根据ModeType 的值更改IsEditable。这将允许您设置用户输入与列表中的任何项目都不匹配的文本的能力。

对于可编辑的ComboBox,您必须使用Text 属性。 SelectedValueSelectedItem 仅在从下拉列表中选择项目时有效,在输入自定义文本时无效。

【讨论】:

  • 感谢基思。我将尝试您的建议,如有任何问题,我会回来澄清。
  • 我已使用修改后的代码进行了编辑。我被困在两个问题领域。你能帮我看看吗?
  • 我应该将此作为单独的问题发布吗?
  • @jamilia 我用应该解决可编辑ComboBox 的内容更新了我的答案,但我不确定其余的。对于这些新问题,您最好开始第二个问题。
  • 谢谢,这行得通!我将分别发布其余部分。一个简单的问题,通过上述设置,是否可以仅在列表为 NullorEmpty 时进行编辑?如果有一个包含他们应该只能选择的值的列表,我不希望用户输入任何输入。只有当列表为空或为空时,他们才能进行编辑。这可能吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多