wpf 我如何用datagrid中列出的数据绑定对象组合静态文本“new Operation Class”?

91zkwejq  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(129)

我的WPF应用程序中有一个数据网格。
此数据网格绑定到一个ObservableCollection,该集合称为OperationClasses,定义如下。
类型OperationClass由3个属性组成,分别为Name、Start和End。
我想知道如何将OperationClass作为datagrid行添加到DataGridList,方法是单击带有文本“new Operation Class”的最后一行,如图中所示(作为附件)。
具有示例值的DataGrid图片:

最终用户输入名称以及起始值和终止值后,文本“new Operation Class”将显示在下一行,即新的最后一行。

如何使用DataGrid中列出的数据绑定对象编写静态文本“new Operation Class”?

public ObservableCollection<OperationClass> OperationClasses
{
    get
    {
        return _operationClasses;
    }
    set
    {
        SetProperty(ref _operationClasses, value);
    }
}

我试图找到一种方法来使用CompositeCollection,以便组合数据绑定对象(OperationClass)和静态文本“新操作类”。但在当前阶段我无法成功。

rsl1atfo

rsl1atfo1#

首先,我想感谢你的宝贵的职位。但我有一些关于添加新项目操作的问题。我定义的问题,通过分享相应的图像如下所示。用户输入名称和开始和结束值后,然后文本“新操作类”应显示在下一行,这是新的最后一行。换句话说,属性名称,“开始”和“结束”是必须填写的列,以便占位符显示在下一行中。除此之外,即使我可以选择新项目占位符行作为选定行,但我不能为数据绑定记录这样做。如果您有机会通知我,我将非常高兴。
Before adding new Item
After adding new item
Selected New Item Row
Selected Data Bound Item Row
为了使它更简单,我将分享如下所示的XAML代码。

<UserControl.Resources>
        <ResourceDictionary>

            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding DataContext.SelectedTreeItem.Name, Mode=OneWay}"></Setter>
            </Style>
            <Style TargetType="DataGridCell">
                <Setter Property="BorderBrush" Value="Gainsboro"></Setter>
                <Setter Property="BorderThickness" Value="0"></Setter>
            </Style>
            <Style TargetType="DataGridRow">
                <Style.Triggers>

                    <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                        <Setter Property="Background" Value="{StaticResource ContentBackgroundColorBrush}"/>
                    </Trigger>
                    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                        <Setter Property="Background" Value="White"/>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Foreground" Value="DarkBlue"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </UserControl.Resources>
    <AdornerDecorator>
        <Grid>
            <DataGrid  x:Name="OperationClassDataGrid"
                       ItemsSource="{Binding PlantMachine.OperationClasses, UpdateSourceTrigger=PropertyChanged}"                     
                       AlternationCount="2"
                       CanUserAddRows="True"
                       CanUserDeleteRows="True"
                       CanUserReorderColumns="False"
                       CanUserResizeColumns="False"
                       CanUserSortColumns="False"
                       AutoGenerateColumns="False" 
                       IsReadOnly="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Visibility="Hidden" Header="{DynamicResource Plant.OperationClass.List.Header.Key}" Binding="{Binding OperationKey}" Width="Auto" SortDirection="Ascending"/>
                    <DataGridTemplateColumn Header="{DynamicResource Plant.OperationClass.List.Header.Name}">
                        <DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate DataType="{x:Type model:OperationClass}">
                                <TextBlock Text="{Binding OperationName}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellEditingTemplate>

                        <!-- Instead of defining the CellTemplate explicitly, 
           we assign the CellTemplateSelector instead -->
                        <DataGridTemplateColumn.CellTemplateSelector>
                            <local:OperationClassTemplateSelector>
                                <local:OperationClassTemplateSelector.DefaultTemplate>
                                    <DataTemplate DataType="{x:Type model:OperationClass}">
                                        <TextBox Text="{Binding OperationName}" />
                                    </DataTemplate>
                                </local:OperationClassTemplateSelector.DefaultTemplate>
                                <local:OperationClassTemplateSelector.PlaceholderTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="new operation class..." />
                                    </DataTemplate>
                                </local:OperationClassTemplateSelector.PlaceholderTemplate>
                            </local:OperationClassTemplateSelector>
                        </DataGridTemplateColumn.CellTemplateSelector>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Header="{DynamicResource Plant.OperationClass.List.Header.Start}" Binding="{Binding RangeStartValue}" Width="Auto" SortDirection="Ascending"/>
                    <DataGridTextColumn Header="{DynamicResource Plant.OperationClass.List.Header.End}" Binding="{Binding RangeEndValue}" Width="Auto" SortDirection="Ascending"/>
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Image Source="/Resources/Images/Delete.png"  Width="125" Height="30" HorizontalAlignment="Right">
                                    <Image.InputBindings>
                                        <MouseBinding  Gesture="LeftClick" CommandParameter="{Binding Path=Key}"  Command="{Binding DataContext.RemoveOperationClassCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"    />
                                    </Image.InputBindings>
                                </Image>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
        </AdornerDecorator>
</UserControl>
pzfprimi

pzfprimi2#

您需要提供一个DataTemplateSelector,以便将专用的DataTemplate应用于占位符列。
首先,占位符项(或占位符表格行)必须通过将DataGrid.CanUserAddRows设置为true来启用。默认值为true,因此请确保不要显式将其设置为false
下面的示例假定您希望占位符文本填充第一列。但是,您可以按照下面的模式为任何列添加占位符文本。
按照您的代码,该示例假定用于填充DataGrid的数据模型是OperationClass,它具有两个虚构属性以构成两列:

操作类.cs

class OperationClass : INotifyPropertyChanegd
{
  public string TextDataFirstColumn { get; set; }
  public string TextDataSecondColumn { get; set; }
}

首先,定义DataTemplateSelector

操作类模板选择器.cs

class OperationClassTemplateSelector : DataTemplateSelector
{
  public DataTemplate DefaultTemplate { get; set; }
  public DataTemplate PlaceholderTemplate { get; set; }

  public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    => item switch
    {
      OperationClass _ => this.DefaultTemplate,
      var dataItem when dataItem is not null => this.PlaceholderTemplate,
      _ => base.SelectTemplate(item, container),
    };
}

第二步是显式定义列模板。
将包含占位符文本的列定义为DataGridTemplateColumn非常重要。这是允许分配DataTemplateSelector实现所必需的。
占位符行的第一列将显示 “Add new item..." 作为占位符文本:

<DataGrid ItemsSource="{Binding OperationClassItems}"
          AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTemplateColumn Header="1st Column">
      <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate DataType="{x:Type local:OperationClass}">
          <TextBox Text="{Binding TextDataFirstColumn}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellEditingTemplate>

      <!-- Instead of defining the CellTemplate explicitly, 
           we assign the CellTemplateSelector instead -->
      <DataGridTemplateColumn.CellTemplateSelector>
        <local:OperationClassTemplateSelector>
          <local:OperationClassTemplateSelector.DefaultTemplate>
            <DataTemplate DataType="{x:Type local:OperationClass}">
              <TextBlock Text="{Binding TextDataFirstColumn}" />
            </DataTemplate>
          </local:OperationClassTemplateSelector.DefaultTemplate>

          <local:OperationClassTemplateSelector.PlaceholderTemplate>
            <DataTemplate>
              <TextBlock Text="Add new item..." />
            </DataTemplate>
          </local:OperationClassTemplateSelector.PlaceholderTemplate>
        </local:OperationClassTemplateSelector>
      </DataGridTemplateColumn.CellTemplateSelector>
    </DataGridTemplateColumn>

    <DataGridTextColumn Header="2nd Column" 
                        Binding="{Binding TextDataSecondColumn}" />
  </DataGrid.Columns>
</DataGrid>

相关问题