简体   繁体   English

在xaml中获取数据网格内部的scrollviewer的宽度

[英]Get the width of the scrollviewer inside of a datagrid in xaml

I am building a UI in xaml (WPF), and I have a datagrid with autogenerated columns which fills its container (a dockpanel ), but also has frozen columns. 我正在xaml(WPF)中构建UI,并且我有一个带有自动生成的列的datagrid ,该列会填充其容器( dockpanel ),但也具有冻结列。

Depending on the size of the window and the amount of data in the grid, the none frozen columns on the right automatically get an horizontal scrollbar. 根据窗口的大小和网格中的数据量,右侧的非冻结列会自动获得水平滚动条。

I am interested in retrieving the width of the scrollviewer from inside the datagrid that it is visible when the datagrid becomes bigger than the dockpanel , possibly in xaml directly to bind it to another element, or in the code behind if the first option is not possible. 我感兴趣的是从datagrid内检索scrollviewer的宽度,当datagrid变得比dockpanel大时可以看到它,可以在xaml中直接将其绑定到另一个元素,或者在后面的代码中,如果第一种选择不可行。 I would also like to retrieve the width of the content inside the scrollviewer . 我还想检索scrollviewer内部内容的宽度。

I thought of getting the actual width of the surrounding elements and do a bit of calculation but that sounds tedious... 我想到获取周围元素的实际宽度并进行一些计算,但这听起来很乏味...

Does anybody have a suggestion? 有人有建议吗?

Thanks 谢谢

With the help of this post "access-scrollview-properties-of-a-datagrid-in-wpf" I managed to access the scrollviewer of the datagrid via the visual tree. 借助这篇文章“在wpf中访问datagrid的access-scrollview-properties”,我设法通过可视化树访问了datagridscrollviewer

However, despite checking several properties of the scrollviewer , I wasn't able to find what I am looking for. 但是,尽管检查了scrollviewer几个属性,但我找不到要查找的内容。

So, I eventually calculated the size myself (width of the datagrid - width of the frozen columns). 因此,我最终自己计算了大小( datagrid宽度-冻结列的宽度)。 I think that I will also calculate the width of the other columns to get the width of the content inside the scrollviewer ... 我认为我还将计算其他列的宽度,以获取scrollviewer内部内容的宽度...

Here is a simple example to run in Blend (proj name: GridScrollViewer ): 这是一个在Blend中运行的简单示例(项目名称: GridScrollViewer ):

MainWindow.xaml: 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: 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();
        }

    }
}

This mostly answer my question, but if anybody has a better alternative, I'd be very happy to read about it. 这基本上可以回答我的问题,但是如果有人有更好的选择,我将很高兴阅读它。

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

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