【问题标题】:WPF DataGrid SelectAll Button appearing once DataGrid is Loaded加载 DataGrid 后出现 WPF DataGrid SelectAll 按钮
【发布时间】:2018-02-11 07:29:56
【问题描述】:

我是 WPF 新手,我正在开发一个项目,我正在使用 WPF 和 DataGrid 来显示 DataTable。

我的列标题和行标题都可见,我遇到的问题是在调用 WPF 窗口的方法完成之前,DataGrid 左上角的 SelectAll 按钮不会出现。这会导致列标题未对齐,直到出现 SelectAll 按钮。

我在一个非常简单的项目中重新创建了这个问题。

我可以在设计模式下看到 SelectAll 按钮,结果还是一样。有人可以帮忙吗?下面的图片显示了我在说什么。

下面是我的 XAML,后面是创建 DataTable 的 C#

<Window
    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"
    x:Class="WpfApplication1.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="450px" Width="800px">
<Window.Resources>
    <Style TargetType="{x:Type Button}"
           x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver"/>
                                <VisualState x:Name="Pressed"/>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                                       Storyboard.TargetName="Arrow">
                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                    Value="{x:Static Visibility.Collapsed}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Rectangle x:Name="Border"
                                   SnapsToDevicePixels="True">
                            <Rectangle.Stroke>
                                <LinearGradientBrush EndPoint="0.5,1"
                                                     StartPoint="0.5,0">
                                    <GradientStop Color="{DynamicResource BorderLightColor}"
                                                  Offset="0" />
                                    <GradientStop Color="{DynamicResource BorderMediumColor}"
                                                  Offset="1" />
                                </LinearGradientBrush>
                            </Rectangle.Stroke>
                            <Rectangle.Fill>
                                <LinearGradientBrush EndPoint="0.5,1"
                                                     StartPoint="0.5,0">
                                    <GradientStop Color="{DynamicResource BorderLightColor}"
                                                  Offset="0" />
                                    <GradientStop Color="{DynamicResource BorderMediumColor}"
                                                  Offset="1" />
                                </LinearGradientBrush>
                            </Rectangle.Fill>
                        </Rectangle>

                        <Polygon x:Name="Arrow"
                                 HorizontalAlignment="Right"
                                 Margin="8,8,3,3"
                                 Opacity="0.55"
                                 Points="0,10 10,10 10,0"
                                 Stretch="Uniform"
                                 VerticalAlignment="Bottom">
                            <Polygon.Fill>
                                <SolidColorBrush Color="White" />
                            </Polygon.Fill>
                        </Polygon>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>

<Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="73*"/>
        <ColumnDefinition Width="502*"/>
        <ColumnDefinition Width="120"/>
        <ColumnDefinition Width="120"/>

    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="30"/>
        <RowDefinition Height="20"/>
    </Grid.RowDefinitions>
    <Button x:Name="BtnImport" Content="Import"  Grid.Row="2" Grid.Column="3" Height="20" Width="100">
        <Button.ToolTip>
            <ToolTip>
                <StackPanel>
                    <TextBlock FontWeight="BOLD"><Run Text="Import to AutoCAD"/></TextBlock>
                    <TextBlock><Run Text="Click or press ALT+ENTER"/></TextBlock>
                </StackPanel>
            </ToolTip>
        </Button.ToolTip>
    </Button>
    <Button x:Name="BtnCancel" Content="Cancel"  Grid.Row="2" Grid.Column="2" Height="20" Width="100">

        <Button.ToolTip>
            <ToolTip>
                <StackPanel>
                    <TextBlock FontWeight="BOLD"><Run Text="Cancel"/></TextBlock>
                    <TextBlock><Run Text="Click or press ESCAPE"/></TextBlock>
                </StackPanel>
            </ToolTip>
        </Button.ToolTip>
    </Button>
    <StatusBar Grid.Row="3" Grid.ColumnSpan="4" Grid.Column="0">
        <StatusBarItem >
            <TextBlock x:Name="AppsVer"><Run Text="AppsVer"/></TextBlock>
        </StatusBarItem>
    </StatusBar>

    <DataGrid x:Name="ExportGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" ColumnHeaderHeight="50" HeadersVisibility="All" 
              AutoGenerateColumns="True" RowHeaderWidth="40"/>
</Grid>

using System.Data;

namespace WpfApplication1
{
    public partial class MainWindow
    {
    public MainWindow()
    {
        InitializeComponent();

        ExportGrid.ItemsSource = MakeTable().DefaultView;
    }

    public static DataTable MakeTable()
    {
        var tbl = new DataTable();

        for (int i = 1; i < 5; i++)
        {
            tbl.Columns.Add("Column" + i, typeof(int));
        }

        for (int j = 0; j <= 30; j++)
        {
            var nuRow = tbl.NewRow();
            for (int k = 0; k < 4; k++)
            {

                nuRow[k] = j;
            }
            tbl.Rows.Add(nuRow);
        }
        return tbl;
    }
  }
}

【问题讨论】:

  • 我无法重现您的实施问题?窗口一出现,网格就会正确渲染。您能否提供进一步的解释或问题可见的代码?
  • 您好 Eike B 感谢您的评论。你编译这个并从.exe运行吗?因为我同意 .exe 它呈现得很好。如果你从 Visual Studio 内部运行它,你就会看到我描述的症状。
  • 我正在处理的项目是 AutoCAD 的插件,即使我构建了一个发布版本并在 AutoCAD 中运行而不是从 Visual Studio 进行调试,我仍然会得到列标题的变化。
  • 我用调试器从 vs 运行它。结果还是一样
  • 与它正确呈现的结果相同还是与我报告的结果相同?

标签: c# wpf xaml datatable datagrid


【解决方案1】:

我无法按照您描述的方式重现您的问题。

但根据您的描述,这可能是一种使用异步方法填充网格的解决方案。在这种情况下,视图不会阻塞,直到方法完成并且应该正确绘制网格。

我添加了一个代码 sn-p,它将异步填充网格:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MakeTable();
        }

        public async void MakeTable()
        {
            var task = await Task<DataTable>.Factory.StartNew(() =>
            {
                var tbl = new DataTable();
                for (int i = 1; i < 5; i++)
                {
                    tbl.Columns.Add("Coloumn" + i, typeof(int));
                }

                for (int j = 0; j <= 30; j++)
                {
                    var nuRow = tbl.NewRow();
                    for (int k = 0; k < 4; k++)
                    {

                        nuRow[k] = j;
                    }
                    Thread.Sleep(50);
                    tbl.Rows.Add(nuRow);
                }

                return tbl;
            });

            ExportGrid.ItemsSource = task.DefaultView;
        }
    }

【讨论】:

  • 您好 Eike B。感谢您的评论和建议。我已经尝试了您上面的代码 sn-p 并且问题仍然存在。有什么方法可以将 DataGrid 创建为对象,然后将其传递给窗口?那还会有帮助吗??我已经尝试过并且可以成功创建网格,但是我无法让它显示在窗口上。
  • 嘿 K.Scott,我不确定您要做什么?您想在后面的代码中创建完整的网格,然后将其添加到您的视图中吗?好吧,你可以这样做,但它是一个讨厌的解决方法。如何做到这一点,您应该搜索类似在 CodeBehind 中创建用户控件的内容。是否有可能,该问题基于某些继承到您当前控件的数据模板?这可能是我无法重现此问题的原因。您如何导航到视图?你在使用像 Prism 这样的库吗?
猜你喜欢
  • 2020-11-28
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多