4

I have a Grid having two columns. One column is twice the width as other.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="2*" />
    </Grid.ColumnDefinitions>      
    <TextBox Grid.Column="0" Text="12"/>
    <TextBox Grid.Column="1" Text="" />
</Grid>

But during runtime when i type in second text box the width changes without maintaining the 1:2 ratio.
I dont want to keep fixed width. The width will be changed at runtime based on user entry.
I want the width to be in 1:2 ratio even if the width changes at runtime?

Johan Larsson
  • 17,112
  • 9
  • 74
  • 88
Olivarsham
  • 1,701
  • 5
  • 25
  • 51

2 Answers2

2

This can be done like this:

MainWindow.xaml

<Grid>
    <Grid Width="{Binding Path=GridWidth}"
          Margin="0,60,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>
        <TextBox Grid.Column="0" Text="Single 33%"/>
        <TextBox Grid.Column="1" Text="Double 67%" />
    </Grid>
    <Button Content="Increase" Height="34" HorizontalAlignment="Left" Margin="19,12,0,0" Name="button1" VerticalAlignment="Top" Width="90" Click="button_Click" />
    <Button Content="Decrease" Height="34" HorizontalAlignment="Left" Margin="120,12,0,0" Name="button2" VerticalAlignment="Top" Width="90" Click="button_Click" />
</Grid>

I have two buttons that increase or decrease the total grid width for illustration.

MainWindows.cs

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public static readonly DependencyProperty GridWidthProperty = DependencyProperty.Register("GridWidth", typeof(Double), typeof(MainWindow), new UIPropertyMetadata(300d));
    public Double GridWidth
    {
        get { return (Double)GetValue(GridWidthProperty); }
        set
        {
            SetValue(GridWidthProperty, value);
            NotifyPropertyChanged("GridWidth");
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        if (sender == button1)
            this.GridWidth += 50;
        else if (sender == button2)
            this.GridWidth -= 50;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(String PropertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
    }
}
Mats Magnem
  • 1,375
  • 1
  • 10
  • 21
2

Here is another, alternative answer that you can modify into your needs.

In this example, you can enter the width of your grid in the textbox in the first column. Or you can expand or decrease the width with the button. Just for illustration. You may have to change this for your purpose.

MainWindow.cs

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public static readonly DependencyProperty GridWidthProperty = DependencyProperty.Register("GridWidth", typeof(Double), typeof(MainWindow), new UIPropertyMetadata(300d, OnGridWidthPropertyChanged));
    public Double GridWidth
    {
        get { return (Double)GetValue(GridWidthProperty); }
        set
        {
            SetValue(GridWidthProperty, value);
            NotifyPropertyChanged("GridWidth");
        }
    }

    public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth", typeof(String), typeof(MainWindow), new UIPropertyMetadata("100", OnColumnWidthPropertyChanged));
    public String ColumnWidth
    {
        get { return (String)GetValue(ColumnWidthProperty); }
        set
        {
            SetValue(ColumnWidthProperty, value);
            NotifyPropertyChanged("ColumnWidth");
        }
    }

    private static void OnGridWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        MainWindow ctl = sender as MainWindow;

        ctl.doGridWidthChanged();
        ctl = null;
    }

    private static void OnColumnWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        MainWindow ctl = sender as MainWindow;

        ctl.doColumnWidthChanged();
        ctl = null;
    }

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        if (sender == button1)
            this.GridWidth += 50;
        else if (sender == button2)
            this.GridWidth -= 50;
    }

    private void doGridWidthChanged()
    {
        if (Double.IsNaN(this.GridWidth))
            return;

        this.ColumnWidth = Math.Round((this.GridWidth / 3), 2).ToString();
    }

    private void doColumnWidthChanged()
    {
        Double columnwidthval = Double.NaN;

        if (!String.IsNullOrEmpty(this.ColumnWidth) && Double.TryParse(this.ColumnWidth, out columnwidthval))
            this.GridWidth = columnwidthval * 3;
        else
            this.ColumnWidth = Math.Round((this.GridWidth / 3), 2).ToString();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(String PropertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
    }
}

And here is my XAML code.

MainWindow.xaml

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication3"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <Grid Margin="0,60,0,0"
              Width="{Binding Path=GridWidth}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="2*" />
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" Background="GhostWhite" />
            <Border Grid.Column="1" Background="AliceBlue" />
            <Border Grid.ColumnSpan="2" BorderBrush="DimGray" BorderThickness="1" />
            <StackPanel Grid.Column="0" Orientation="Vertical" Margin="3">
                <TextBlock Text="Single" />
                <TextBox Text="{Binding Path=ColumnWidth, Mode=TwoWay}" />
            </StackPanel>
            <StackPanel Grid.Column="1" Orientation="Vertical" Margin="3">
                <TextBlock Text="Double" />
            </StackPanel>
        </Grid>
        <Button Content="Increase" Height="34" HorizontalAlignment="Left" Margin="19,12,0,0" Name="button1" VerticalAlignment="Top" Width="90" Click="button_Click" />
        <Button Content="Decrease" Height="34" HorizontalAlignment="Left" Margin="120,12,0,0" Name="button2" VerticalAlignment="Top" Width="90" Click="button_Click" />
    </Grid>
</Window>

Hope that helps!

Mats Magnem
  • 1,375
  • 1
  • 10
  • 21