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

发布于 2024-11-27 02:40:44 字数 2274 浏览 3 评论 0原文

我的问题与此类似;

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

|--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 --------------------------------------------------------------|

这非常令人沮丧,我只是希望 Row Details 不更改 DataGrid 的宽度,这有那么多要求吗? :)

My problem is similar to this one;

Except I would like row details never to exceed the width of the columns it spans.

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

I have tried AreRowDetailsFrozen and this had no effect. I have also tried binding to the parent Grid's actual width (OneWay) but this causes the width to exceed that of my two screens.

Here is my current attempt (simplified);

  <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>

This results in the following;

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

Binding the width of the TextBox to any parent container (Grid, DataGrid, ItemsPresenter):

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

Results in:

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

It's very frustrating, I just want the Row Details not to change the width of the DataGrid, is that so much to ask? :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦忆晨望 2024-12-04 02:40:44

实现此目的的唯一方法是更改​​ 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>

希望这有帮助。

The only way to accomplish this is to change DataGridRow ControlTemplate. There we can bind row details host width (DataGridDetailsPresenter) to width of cells. For example:

<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>

Hope this helps.

最偏执的依靠 2024-12-04 02:40:44

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

这里的答案感觉像是一个解决方法,所以我做了一些研究并做了
在 Telerik 论坛上找到解决方案,因为我们使用他们的
RadGridView。事实证明该解决方案也适用于 DataGrid。

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



    <数据模板>
        <边框>
            
        
    
 

I answered a similar question here DataGrid RowDetails Width problem

The answers here felt like a workaround so I did some research and did
find the solution on the Telerik forums, since we use their
RadGridView. Turned out the solution worked for DataGrid as well.

The key is to set the ScrollViewer.HorizontalScrollBarVisibility
property to Disabled, see example below.

<DataGrid ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <Border>
            <TextBlock Foreground="White" Text="{Binding RowDetails}"
                       TextWrapping="Wrap"/>
        </Border>
    </DataTemplate>
</DataGrid.RowDetailsTemplate> </DataGrid>
半世晨晓 2024-12-04 02:40:44

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

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 ,则该常量值不适合 - 和转换器。

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

I've found another way to fix the Problem:

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

This prevents you from using constant values (e.g. '6') - which won't fit, if someone set DataGrid.RowHeaderWidth - and Converters.

I've added this to the DataGrid.LoadingRowDetails event handler, since I am already tweaking the RowDetails in some other ways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文