【问题标题】:Get the width of the scrollviewer inside of a datagrid in xaml在 xaml 中获取数据网格内的滚动查看器的宽度
【发布时间】:2016-12-15 19:07:40
【问题描述】:

我在 xaml (WPF) 中构建 UI,我有一个 datagrid 自动生成的列填充其容器(dockpanel),但也有冻结列。

根据窗口大小和网格中的数据量,右侧未冻结的列会自动获得水平滚动条。

我有兴趣从datagrid 内部检索scrollviewer 的宽度,当datagrid 大于dockpanel 时可见,可能在xaml 中直接将其绑定到另一个元素,或者如果第一个选项不可能,则在后面的代码中。我还想检索scrollviewer 中内容的宽度。

我想获取周围元素的实际宽度并进行一些计算,但这听起来很乏味...

有人有建议吗?

谢谢

【问题讨论】:

    标签: c# wpf xaml datagrid


    【解决方案1】:

    在这篇文章"access-scrollview-properties-of-a-datagrid-in-wpf" 的帮助下,我设法通过可视化树访问了datagridscrollviewer

    但是,尽管检查了 scrollviewer 的多个属性,我还是找不到我要查找的内容。

    所以,我最终自己计算了大小(datagrid 的宽度 - 冻结列的宽度)。我想我也会计算其他列的宽度来获得scrollviewer内内容的宽度...

    这是一个在 Blend 中运行的简单示例(项目名称:GridScrollViewer):

    MainWindow.xaml:

    <Window x:Class="GridScrollViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GridScrollViewer"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel
        LastChildFill="True"
        Margin="10">
    
        <StackPanel
            Width="auto"
            Orientation="Horizontal"
            DockPanel.Dock="Bottom">
            <TextBlock Text="Scrollviewer offset: "/>
            <TextBlock Name="myScrollViewerOffsetText"  Text=""/>
        </StackPanel>
    
        <StackPanel
            Width="auto"
            Orientation="Horizontal"
            DockPanel.Dock="Bottom">
            <TextBlock Text="Scrollviewer width?: "/>
            <TextBlock Name="myScrollViewerText"  Text=""/>
        </StackPanel>
    
        <StackPanel
            Width="auto"
            Orientation="Horizontal"
            DockPanel.Dock="Bottom">
            <TextBlock Text="Expected value for scrollviewer width: "/>
            <TextBlock Name="myExpectedValueText"  Text=""/>
        </StackPanel>
    
        <StackPanel
            Width="auto"
            Orientation="Horizontal"
            DockPanel.Dock="Bottom">
            <TextBlock Text="First four columns width: "/>
            <TextBlock Name="myColumnsText" Text=""/>
        </StackPanel>
    
        <StackPanel
            Width="auto"
            Orientation="Horizontal"
            DockPanel.Dock="Bottom">
            <TextBlock Text="Datagrid width: "/>
            <TextBlock Text="{Binding ElementName=myGrid, Path=ActualWidth}"/>
        </StackPanel>
    
        <DataGrid
            ItemsSource="{Binding}"
            Name="myGrid"
            DockPanel.Dock="Top"
            Margin="0,0,0,10"
            FrozenColumnCount="4"
            HorizontalScrollBarVisibility="Visible"
            HeadersVisibility="Column"
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            CanUserResizeColumns="True"
            LayoutUpdated="myGrid_LayoutUpdated"
            />
    
    </DockPanel>
    

    MainWindow.xaml.cs:

    using System;
    using System.Data;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace GridScrollViewer
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                CreateDataGrid();
            }
    
            public void CreateDataGrid()
            {
                DataTable dt = new DataTable();
    
                dt.Columns.Add("Col 1", typeof(string));
                dt.Columns.Add("Col 2", typeof(string));
                dt.Columns.Add("Col 3", typeof(string));
                dt.Columns.Add("Col 4", typeof(string));
                dt.Columns.Add("Col 5", typeof(int));
                dt.Columns.Add("Col 6", typeof(int));
                dt.Columns.Add("Col 7", typeof(int));
                dt.Columns.Add("Col 8", typeof(int));
                dt.Columns.Add("Col 9", typeof(int));
                dt.Columns.Add("Col 10", typeof(int));
                dt.Columns.Add("Col 11", typeof(int));
                dt.Columns.Add("Col 12", typeof(int));
                dt.Columns.Add("Col 13", typeof(int));
                dt.Columns.Add("Col 14", typeof(int));
    
                for (int i = 0; i < 10; i++)
                {
                    dt.Rows.Add("First field",
                        "Second field",
                        "Third field",
                        "Fourth field",
                        100*i+i,
                        100 * i + i+1,
                        100 * i + i+2,
                        100 * i + i+3,
                        100 * i + i+4,
                        100 * i + i+5,
                        100 * i + i+6,
                        100 * i + i+7,
                        100 * i + i+8,
                        100 * i + i+9);
                }
    
                myGrid.DataContext = dt;
            }
    
            public void UpdatemyColumnsText()
            {
                double size = 0;
                if (myGrid.Columns.Count > 4)
                {
                    size = myGrid.Columns[0].ActualWidth
                    + myGrid.Columns[1].ActualWidth
                    + myGrid.Columns[2].ActualWidth
                    + myGrid.Columns[3].ActualWidth;
                }
                myColumnsText.Text = ((int)size).ToString();
            }
    
            public void UpdateScrollViewerText()
            {
                ScrollViewer sc = (ScrollViewer)VisualTreeHelper.GetChild(
                    (VisualTreeHelper.GetChild(myGrid, 0)), 0);
                myScrollViewerText.Text = "actual width: " + (int)sc.ActualWidth
                    +" - desired size: " + (int)sc.DesiredSize.Width
                    +" - render size: " + (int)sc.RenderSize.Width
                    +" - viewport: " + (int)sc.ViewportWidth;
    
                myScrollViewerOffsetText.Text = ((int)sc.HorizontalOffset).ToString();
            }
    
            public void UpdateExpectedWidth()
            {
                double expectedWidth = 0;
                if (myGrid.Columns.Count > 4)
                {
                    expectedWidth = myGrid.ActualWidth -(myGrid.Columns[0].ActualWidth
                    + myGrid.Columns[1].ActualWidth
                    + myGrid.Columns[2].ActualWidth
                    + myGrid.Columns[3].ActualWidth);
                }
                myExpectedValueText.Text = ((int)expectedWidth).ToString();
            }
    
            private void myGrid_LayoutUpdated(object sender, EventArgs e)
            {
                UpdatemyColumnsText();
                UpdateScrollViewerText();
                UpdateExpectedWidth();
            }
    
        }
    }
    

    这主要回答了我的问题,但如果有人有更好的选择,我很乐意阅读。

    【讨论】:

      猜你喜欢
      • 2022-08-18
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多