繁体   English   中英

C#/ WPF-DataGrid-将RowDetails中的文本框的宽度绑定到包含的DataGrid的宽度

[英]C# / WPF - DataGrid - Binding the Width of a TextBox in RowDetails to that of the containing DataGrid

我的问题与此类似。

除非我希望行详细信息永远不要超过它跨越的列的宽度。

|--0--|--1--|--2--|--3--|--4--|
|---------Row-Details---------|

我已经尝试过AreRowDetailsFrozen ,这没有效果。 我还尝试了绑定到父网格的实际宽度(OneWay),但这导致宽度超过了我两个屏幕的宽度。

这是我目前的尝试(简化);

  <Grid>
    <DataGrid x:Name="Grid" 
              Grid.Row="1" 
              ItemsSource="{Binding Collection}"
              IsReadOnly="True"
              AutoGenerateColumns="False" 
              ColumnWidth="Auto"
              CanUserResizeColumns="False"
              CanUserResizeRows="False"
              RowDetailsVisibilityMode="VisibleWhenSelected"
              AreRowDetailsFrozen="True"
              SelectionUnit="FullRow"
              VerticalAlignment="Top"
              HorizontalAlignment="Center">
        <DataGrid.RowDetailsTemplate>
           <!-- Begin row details section. -->
           <DataTemplate>
               <TextBox DataContext="{Binding ErrorMessage}" 
                       IsReadOnly="True"
                       Margin="5"
                       BorderBrush="Transparent"
                       ScrollViewer.VerticalScrollBarVisibility="Auto"
                       ScrollViewer.CanContentScroll="True"
                       TextWrapping="Wrap"
                       Text="{Binding .}">
               </TextBox>
           </DataTemplate>
        </DataGrid.RowDetailsTemplate>
   </DataGrid>
  </Grid>

结果如下:

|--0--|--1--|--2--|--3--|--4--|
|---------Row-Details are as wide as the longest row in their content ---------|

将TextBox的宽度绑定到任何父容器(Grid,DataGrid,ItemsPresenter):

Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Path=ActualWidth, Mode=OneWay}"

结果是:

                              |------Viewable Area-------|
|---- Columns ----|
|---------Row-Details --------------------------------------------------------------|

这非常令人沮丧,我只希望“行详细信息”不更改DataGrid的宽度,是否有那么多要求? :)

实现此目的的唯一方法是更改​​DataGridRow ControlTemplate。 在那里,我们可以将行详细信息主机宽度(DataGridDetailsPresenter)绑定到单元格的宽度。 例如:

<Style x:Key="{x:Type dg:DataGridRow}" TargetType="{x:Type dg:DataGridRow}">
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
    <Setter Property="ValidationErrorTemplate">
      <Setter.Value>
        <ControlTemplate>
          <TextBlock Margin="2,0,0,0" VerticalAlignment="Center" Foreground="Red" Text="!" />
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type dg:DataGridRow}">
          <Border x:Name="DGR_Border"
                  Background="{TemplateBinding Background}"
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}"
                  SnapsToDevicePixels="True">
            <dgp:SelectiveScrollingGrid>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
              </Grid.ColumnDefinitions>

              <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
              </Grid.RowDefinitions>

              <dgp:DataGridCellsPresenter x:Name="cellPresenter" Grid.Column="1"
                                         ItemsPanel="{TemplateBinding ItemsPanel}"
                                         SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

              <dgp:DataGridDetailsPresenter  dgp:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static dg:DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static dg:SelectiveScrollingOrientation.Vertical}}"
                                            Grid.Column="1" Grid.Row="1"
                                            Visibility="{TemplateBinding DetailsVisibility}" Width="{Binding ElementName=cellsPresenter, Path=ActualWidth}"/>

              <dgp:DataGridRowHeader dgp:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"  Grid.RowSpan="2"
                                    Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}}, Path=HeadersVisibility, Converter={x:Static dg:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static dg:DataGridHeadersVisibility.Row}}"/>
            </dgp:SelectiveScrollingGrid>
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

希望这可以帮助。

我在这里回答了类似的问题DataGrid RowDetails宽度问题

此处的答案似乎是一种解决方法,因此我进行了一些研究,并在Telerik论坛上找到了解决方案,因为我们使用了他们的RadGridView。 原来该解决方案也适用于DataGrid。

关键是将ScrollViewer.Horizo​​ntalScrollBarVisibility属性设置为Disabled,请参见下面的示例。

 <DataGrid ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <DataGrid.RowDetailsTemplate> <DataTemplate> <Border> <TextBlock Foreground="White" Text="{Binding RowDetails}" TextWrapping="Wrap"/> </Border> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid> 

我找到了另一种解决问题的方法:

private void GridOnLoadingRowDetails(object sender, DataGridRowDetailsEventArgs e)
{
    var dataGridColumnHeadersPresenter = FindVisualChild<DataGridColumnHeadersPresenter>((DataGrid)sender);
    e.DetailsElement.SetBinding(WidthProperty, new Binding("ActualWidth") { Source = dataGridColumnHeadersPresenter });
}

这样可以防止您使用常量值(例如'6')-如果有人设置了DataGrid.RowHeaderWidth和Converters,则该值将不合适。

我已经将其添加到DataGrid.LoadingRowDetails事件处理程序中,因为我已经通过其他方式调整了RowDetails。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM