简体   繁体   中英

Create an WPF Object with a dynamic size in code behind

I want to draw a bar chart using grids in wpf. Due to design issues I created a grid with 6 pre-defined rows, although more rows could be added if necessary.

As bars I'd like to use grids aswell (rectangles might also be possible, but i want to write text in them later, which was easier with grids so far)

All bars together next to each other would be 100% of the main grids size, while each bar on it's own is only a fracture (in %) of their combined value. Each bar is in its own row with a small gap in between.

I struggle to find a way to set the size of my bars to a percentage of the size of my main grid.

My code looks like this so far:

XAML:

<Window x:Class="BarChart.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:BarChart"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">

<Grid Height="Auto" Width="Auto">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid Name="MainGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="4"/>
            <RowDefinition/>
            <RowDefinition Height="4"/>
            <RowDefinition/>
            <RowDefinition Height="4"/>
        </Grid.RowDefinitions>
    </Grid>
</Grid>

C#:

    namespace BarChart
{
    /// <summary>
    /// tbd
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            int counter = 1;
            int counter_c = 0;
            double[] values = { 656, 333, 812 };
            SolidColorBrush[] colors = { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Green), new SolidColorBrush(Colors.Blue) };
            double maxValue = 0;
            foreach (double d in values)
            {
                maxValue = maxValue + d;
            }


        InitializeComponent();

        foreach (double d in values)
        {
            if(MainGrid.RowDefinitions.Count > counter)
            {
                RowDefinition row = new RowDefinition();
                MainGrid.RowDefinitions.Add(row);
                RowDefinition gap = new RowDefinition();
                gap.Height = new GridLength(4);
                MainGrid.RowDefinitions.Add(gap);

            }
            Grid gd = new Grid();
            gd.Width = d / maxValue * MainGrid.ActualWidth;
            gd.Background = colors[counter_c];
            Grid.SetRow(gd, counter);
            counter += 2;
            counter_c++;
            MainGrid.Children.Add(gd);
        }

    }
}

Currently neither height nor width (MainGrid.ActualWidth is currently 0) seem to be set to any usable value. I want my bar chart to scale dynamically with every window size (Ofc I'll later need a resize event for that, too. But first i need to be able to draw it once tho).

我无法获得后面代码的宽度

我应该看起来像这样

Looks like you were trying to find the MainGrid.ActualWidth in the constructor, which would be before the control is visual created. To fix this, hook up a ContentRendered event and place the logic there.

public MainWindow()
    {
        this.ContentRendered += MainWindow_ContentRendered;
        InitializeComponent();
    }

    private void MainWindow_ContentRendered(object sender, EventArgs e)
    {
        // Your Logic here...
    }

UserControls don't have this event but you can use the Loaded event instead.

public YourUserControl()
    {
        this.Loaded += YourUserControl_Loaded;
        InitializeComponent();
    }

    private void YourUserControl_Loaded(object sender, RoutedEventArgs e)
    {
        // Your Logic here...
    }

These events will fire off after the controls are created and you will be able to see your ActualWidth property with the appropriate value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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