更改 Datagrid-column's/cell 特定行的宽度

change Datagrid-column's/cell's width for specific rows

如果该行的数据具有指定状态,我目前正在尝试更改该单元格的宽度。每行显示一个包含多个列的 MediaRow,以防出错(MediaRow 的 HasError = true)一些列应该被隐藏,column 'status' 应该被放大并取 space现在隐藏的列。

由于要求具有用户定义的列顺序,我以编程方式创建列。

注意:为了便于阅读,我删除了几列(因此删除了 MediaRow 的属性)。

MediaRow:

public class MediaRow : INotifyPropertyChanged
{
    private string _status = string.Empty;
    private string _barcode = string.Empty;
    private string _medgrp = string.Empty;
    private bool _infield = false;
    private bool _haserror = false;

    public string MedGrp
    {
        get => return _medgrp;
        set { _medgrp = value; NotifyPropertyChanged(); }
    }

    public string Barcode
    {
        get => return _barcode;
        set { _barcode = value; NotifyPropertyChanged(); }
    }

    public string Status
    {
        get => return _status;
        set 
        {
            _status = value; NotifyPropertyChanged();
            HasError = (value.ToLower().StartsWith("error")) ? true : false;
        }
    }

    public bool InField
    {
        get => return _infield;
        set { _infield = value; NotifyPropertyChanged(); }
    }

    public bool HasError
    {
        get => return _haserror;
        set { _haserror = value; NotifyPropertyChanged(); }
    }

    public string Description { get; set; }
}

创建列:

private void PopulateColumns()
{
    ObservableCollection<DataGridColumn> _loccolumns = new ObservableCollection<DataGridColumn>();

    DataGridTextColumn barcodecolumn = new DataGridTextColumn();
    barcodecolumn.Header = ResourceManagerService.GetResourceString("EasyTerminalClient_NG", "ColumnBarcode");
    barcodecolumn.Width = new DataGridLength(Settings.Instance.CheckinColumnTable["barcode"], DataGridLengthUnitType.Star);
    barcodecolumn.Binding = new Binding { Path = new PropertyPath("Barcode"), Mode = BindingMode.TwoWay };
    barcodecolumn.Visibility = Visibility.Hidden;
    barcodecolumn.HeaderStyle = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
    barcodecolumn.HeaderStyle.Setters.Add(new Setter(Control.HorizontalContentAlignmentProperty, HorizontalAlignment.Left));
    barcodecolumn.HeaderStyle.Setters.Add(new Setter(Control.BackgroundProperty, System.Windows.Media.Brushes.Transparent));
    barcodecolumn.HeaderStyle.Setters.Add(new Setter(Control.FontSizeProperty, new Binding { Path = new PropertyPath("headerSize"), Source = (EasyCheck.EasyTerminalClient_NG.Util.FontDetails)App.Current.FindResource("FontDetails") }));

    DataGridTextColumn medgrpcolumn = new DataGridTextColumn();
    medgrpcolumn.Header = ResourceManagerService.GetResourceString("EasyTerminalClient_NG", "ColumnMediaGroup");
    medgrpcolumn.Width = new DataGridLength(Settings.Instance.CheckinColumnTable["mediagroup"], DataGridLengthUnitType.Star);
    medgrpcolumn.Binding = new Binding { Path = new PropertyPath("MedGrp"), Mode = BindingMode.TwoWay };
    medgrpcolumn.Visibility = Visibility.Hidden;
    medgrpcolumn.HeaderStyle = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
    medgrpcolumn.HeaderStyle.Setters.Add(new Setter(Control.HorizontalContentAlignmentProperty, HorizontalAlignment.Left));
    medgrpcolumn.HeaderStyle.Setters.Add(new Setter(Control.BackgroundProperty, System.Windows.Media.Brushes.Transparent));
    medgrpcolumn.HeaderStyle.Setters.Add(new Setter(Control.FontSizeProperty, new Binding { Path = new PropertyPath("headerSize"), Source = (EasyCheck.EasyTerminalClient_NG.Util.FontDetails)App.Current.FindResource("FontDetails") }));
    medgrpcolumn.CellStyle = new Style(typeof(DataGridCell));
    medgrpcolumn.CellStyle.Setters.Add(new Setter(DataGridCell.VisibilityProperty, new Binding() { Path = new PropertyPath("HasError"), Mode = BindingMode.OneWay, Converter = new InverseBool2VisibilityConverter() }));

    DataGridTextColumn statuscolumn = new DataGridTextColumn();
    statuscolumn.Header = ResourceManagerService.GetResourceString("EasyTerminalClient_NG", "ColumnState");
    statuscolumn.Width = new DataGridLength(Settings.Instance.CheckinColumnTable["state"], DataGridLengthUnitType.Star);
    statuscolumn.Binding = new Binding() { Path = new PropertyPath("Status"), Mode = BindingMode.OneWay, Converter = new LanguageConverter(), FallbackValue = "???" };
    statuscolumn.Visibility = Visibility.Hidden;
    statuscolumn.HeaderStyle = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
    statuscolumn.HeaderStyle.Setters.Add(new Setter(Control.HorizontalContentAlignmentProperty, HorizontalAlignment.Left));
    statuscolumn.HeaderStyle.Setters.Add(new Setter(Control.BackgroundProperty, System.Windows.Media.Brushes.Transparent));
    statuscolumn.HeaderStyle.Setters.Add(new Setter(Control.FontSizeProperty, new Binding { Path = new PropertyPath("headerSize"), Source = (EasyCheck.EasyTerminalClient_NG.Util.FontDetails)App.Current.FindResource("FontDetails") }));
    statuscolumn.CellStyle = new Style(typeof(DataGridCell));


    //statuscolumn.CellStyle.Setters.Add(new Setter(DataGridCell.MarginProperty, "-5,-5,-5,0"));
    //statuscolumn.CellStyle.Setters.Add(new Setter(DataGridCell.ActualWidthProperty, 500.0));


    if (Settings.Instance.CheckinColumnSequence != null)
    {
        //string columnnames = "number|barcode|title|mediagroup|branch|expires|fee|state|imagestate|";
        string[] columnSequence = Settings.Instance.CheckinColumnSequence;
        for (int i = 0; i < columnSequence.Length; i++)
        {
            DataGridColumn thiscolumn = null;
            switch (columnSequence[i])
            {
                case "barcode":
                    thiscolumn = barcodecolumn;
                    break;
                case "mediagroup":
                    thiscolumn = medgrpcolumn;
                    break;
                case "state":
                    thiscolumn = statuscolumn;
                    break;
            }
            if (thiscolumn != null)
            {
                thiscolumn.Visibility = Visibility.Visible;
                thiscolumn.DisplayIndex = i;
                _loccolumns.Add(thiscolumn);
            }
        }
        ColumnCollection = _loccolumns;
    }
}

XAML:

<UserControl.Resources>
    <DataTemplate x:Key="RowDetailTemplate">
                <Grid x:Name="RowDetailGrid"
              Width="952"
              Height="Auto"
              Margin="5">
            <Border HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    CornerRadius="5">
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Offset="0" Color="WhiteSmoke" />
                        <GradientStop Offset="0.75" Color="#AAFFFFAA" />
                        <GradientStop Offset="1" Color="#AAFFD455" />
                    </LinearGradientBrush>
                </Border.Background>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Row="0"
                               Margin="10"
                               HorizontalAlignment="Center"
                               FontSize="{Binding headerSize, Source={StaticResource FontDetails}}"
                               FontWeight="Black"
                               Text="Weitere Details" />
                    <TextBlock Grid.Row="1"
                               Margin="10"
                               HorizontalAlignment="Left"
                               Text="{Binding Description}"
                               TextWrapping="WrapWithOverflow" />
                </Grid>
            </Border>
            <Border Margin="0,0,0,0" CornerRadius="5">
                <Border.Background>
                    <RadialGradientBrush Center="0.5,1" GradientOrigin="0,1" Opacity="0.3" RadiusX="0.8" RadiusY="0.8">
                        <GradientStop Offset="1" Color="#AACCCCCC" />
                        <GradientStop Offset="1" Color="WhiteSmoke" />
                    </RadialGradientBrush>
                </Border.Background>
            </Border>
        </Grid>
    </DataTemplate>
</UserControl.Resources>


<DataGrid x:Name="dataGrid1"
    Margin="10,10,0,0"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    AlternationCount="2"
    AutoGenerateColumns="False"
    c:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection, UpdateSourceTrigger=PropertyChanged}"
    ItemsSource="{Binding MediaRowCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"
    MinRowHeight="26"
    RowDetailsTemplate="{StaticResource RowDetailTemplate}"
    RowDetailsVisibilityChanged="dataGrid1_RowDetailsVisibilityChanged"
    Loaded="dataGrid1_Loaded"
    Width="952"
    IsReadOnly="True"
    SelectionMode="Single"
    CanUserReorderColumns="False"
    CanUserResizeColumns="False"
    CanUserSortColumns="False"
    CanUserResizeRows="False"
    HorizontalScrollBarVisibility="Disabled"
    AreRowDetailsFrozen="True"
    HeadersVisibility="Column" VerticalScrollBarVisibility="Auto" >
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="{Binding InField}" Value="False">
                    <Setter Property="Background" Value="Transparent"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding InField}" Value="True">
                    <Setter Property="Background" Value="#ffffffac"/>
                </DataTrigger>      
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <ToggleButton x:Name="RowHeaderToggleButton"
                    Click="ToggleButton_Click"
                    Cursor="Hand"/>
        </DataTemplate>
    </DataGrid.RowHeaderTemplate>
</DataGrid>

在第一步中,我忽略了 HasError 条件,只是尝试将所需的效果应用于状态单元格,但没有成功。我只是得到一个未处理的异常。 (我在 'Create Columns' 部分作为评论留下的相应代码。)

System.ArgumentException: '"-5,-5,-5,0" ist kein gültiger Wert für die Eigenschaft "System.Windows.FrameworkElement.Margin" auf einem "Setter".'

应翻译为:

System.ArgumentException: '"-5,-5,-5,0" is no valid Value for the property "System.Windows.FrameworkElement.Margin" on a "Setter".'

问题:

怎样才能达到想要的效果?
如果 MediaRow 的 HasError == true MedGrp-cell 应该被隐藏并且 Status-cell 应该占用 MedGrp-cells 的 space.
我很乐意接受任何建议,即使它只是针对新状态宽度的固定值。

您不能将 Margin 属性 设置为 string。您应该将其设置为 Thickness:

statuscolumn.CellStyle.Setters.Add(new Setter(DataGridCell.MarginProperty, new Thickness(-5,-5,-5,0))));

这应该摆脱你得到的 ArgumentException