【问题标题】:Set Dynamic Size of WPF-Object in Code Behind在后面的代码中设置 WPF 对象的动态大小
【发布时间】:2018-02-14 16:08:33
【问题描述】:

我目前正在尝试设计一个如下所示的条形图: 每行的行数和条形数可能因我的图表所依赖的数据表而异。 (间隙不是故意的,但不是我的问题atm)

我正在尝试通过使用网格来实现我的条形图。我的 DataTable 为我提供了一个键、一个长度、一个名称和一个父级(这是右侧栏的键,因为每一行只是将右侧栏拆分为较小的栏)。

网格大小目前基于我的主网格,在 XAML-ViewModel 中设置为 900*400。我的条当前设置为它们的 Length/MaxLength * GridLength(而第一个条始终是 MaxLength)并且有一个边距,因为我希望它们从右到左。 我的问题是,我想让这个网格在大小上是动态的,但是如果我没有为我的 MainGrid 设置一个固定大小,我的 Grid 的大小要么是 NaN 要么是 0。

我删除了一些相当混乱的部分,但基本上这是我的代码:

public MainWindow()
{
    InitializeComponent();
    myTable = new DataTable();
}

InitChart(DataTable dt) //Is called from another class when the DataTable changes
{
    Maingrid.Children.Clear(); //Dispose old BarChart
    myTable = dt;
    Grid grid1 = new Grid();
    grid1.Width = MainGrid.Width;
    grid1.Height = MainGrid.Height;
    // Create Rows 
    int Pa = -1;
        foreach (DataRow rw in myTable.Rows)
        {    

            if (Pa != (int)rw["Parent"])
            {
                RowDefinition rdef = new RowDefinition();
                rdef.Height = new GridLength(20);
                grid.RowDefinitions.Add(rdef);
            }
            Pa = (int)rw["Parent"];
        }

    foreach (DataRow row in myTable.Rows)
    {
     int P = (int)row["Parent"];
       foreach (DataRow rw in myTable.Rows)
        {    
            if ((int)rw["Parent"] == P) //Each row splits the right bar of the previous row, all bars in one row have the previous split bar as their Parent. I draw all Bars with the same Parent in one Row. 
            {
                if ((int)rw["Val"] != 0) //Some Bars are disabled or 0. I don't draw them
                {
                    Rectangle rect = new Rectangle();
                    double L = rw["Val"]; //The Value of one Bar
                    rect.Width = L / nMaxValue * grid.Width; //Calculate width of my Rectange based on the maximal value one bar can have
                    rect.Height = 20; //Just a height
                    rect.Margin = new Thickness( grid.Width - nRowValue/nMaxValue * grid.Width, 0, 0, 0); //Margin to display the bars next to each other
                    rect.Fill = Col;
                    rect.HorizontalAlignment = HorizontalAlignment.Left; //Although i want to have my BarChart go from right to left, I align all bars from on the left and then move them with my margin
                    Grid.SetRow(rect, y);
                    nRowValue = nRowValue - (int)rw["Val"];
                    grid1.Children.Add(rect);
                }
            }
        }
    }

    MainGrid.Children.Add(grid1);
}

XAML:

<UserControl x:Class="WpfApp.MainWindow"
    <Grid x:Name="MainGrid"  Background="#f0f0f0" Height="400" Width="900" />
</UserControl>

我也已经尝试过使用 ItemsControl,但我似乎无法让它工作。

【问题讨论】:

  • 您也可以发布您的 XAML 吗?还有更多你的代码隐藏 - 是你的 MainWindow.xaml.cs 文件的代码隐藏,如果是的话 - 构造函数,WindowLoaded 事件等?
  • 我在其中编辑了更多细节。

标签: c# wpf xaml


【解决方案1】:

要使大小动态化,您可以使用 Grid 和 Grid Columns。 Grid 是一个很棒的布局控件,因为它可以使用所有可用空间。只要确保不要在任何时候设置其或其列的宽度。这样,外部控件(如 Page 或 Window)可以控制它使用多少空间。

过程:

  1. 通过查找数据表中的最大长度来确定 maxLength 值。
  2. 将那么多的网格列添加到网格中。确保不要设置列宽度。以下代码与添加*-column相同,这是我们需要的:

    for (int i = 0; i < maxLength; i++)
    {
        MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
    }
    
  3. 为每个条创建矩形,但不要设置它们的宽度或边距。而是设置 Column 和 ColumnSpan。例如:

    var rectangle = new Rectangle
    {
        Fill = new SolidColorBrush(Colors.LightGray),
        Opacity = 0.5,
        Margin = new Thickness(0, -10, 0, 0),
        Height = 66
    };
    
    MyGrid.SetColumn(rectangle, (int)maxLength - data.Length);
    MyGrid.SetColumnSpan(rectangle, data.Length);
    

希望这会有所帮助。如果您遇到任何问题,请告诉我。

【讨论】:

  • 感谢您的回答。我采用了不同的方法,但如果遇到其他问题,我很高兴我有一些东西可以依靠。
猜你喜欢
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多