WPF Layout Binding

I apologize for the length of this post, but this one is banishing me for two days right now. Consider the image below. On Mouseclick on one of the tiles 1-4 tile size and a large tile 5 appear in the middle. Another mouseclick cancels the process. Resizing tiles

I first tried to directly bind the width / height property for rows and columns. It didn't work. The current solution uses the width and height property of the labels to get the resize. The code looks like this:

XAML:

....
<Grid Name ="MainGrid" Background="Crimson">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid Name="LeftGrid" Grid.Column ="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1"/>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Label Grid.Column ="1" Grid.Row ="0"  Background ="Cyan " Width="200" Name="HandleLeftTop" />
        <Label Grid.Column ="0" Grid.Row ="1"  Background ="Cyan " Width="200" Name="HandleLeftSideTop" />
        <Label Grid.Column ="0" Grid.Row ="2"  Background ="Cyan " Width="200" Name="HandleLeftSideBottom"/>
        <Grid Grid.Column ="1" Grid.Row ="1" Background ="Green" MouseDown="Grid_MouseDown">    </Grid>
        <Grid Grid.Column ="1" Grid.Row ="2" Background ="Yellow" MouseDown="Grid_MouseDown_1"></Grid>
    </Grid>

    <Grid Name="RightGrid" Grid.Column ="2">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="1"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1"/>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Label Grid.Column ="0" Grid.Row ="0"  Background ="Cyan " Width="200" Name="HandleRightTop"/>
        <Label Grid.Column ="1" Grid.Row ="1"  Background ="Cyan " Width="200" Name="HandleRightSideTop"/>
        <Label Grid.Column ="1" Grid.Row ="2"  Background ="Cyan " Width="200" Name="HandleRightSideBottom"/>
        <Grid Grid.Column ="0" Grid.Row ="1" Background ="Thistle " MouseDown="Grid_MouseDown_2"></Grid>
        <Grid Grid.Column ="0" Grid.Row ="2" Background ="Tan " MouseDown="Grid_MouseDown_3"></Grid>
    </Grid>

    <Grid Name="MiddleGrid" Grid.Column ="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="1"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <Label Grid.Row ="0"  Background ="Cyan " Width="200" Name="HandleMiddleTop" />
        <Grid Grid.Column ="0" Grid.Row ="1" Background ="Tomato"/>
    </Grid>

</Grid>

      

FROM#

public partial class RTGraphControl : UserControl
{

    private readonly RTGraphControlViewModel _viewModel;

    public RTGraphControl()
    {
        InitializeComponent();
        _viewModel = new RTGraphControlViewModel(this);

        DataContext = _viewModel;

        //.... Binding row heights etc...

        var leftColumnWidthbindingElement = new Binding
        {
            Source = _viewModel,
            Path = new PropertyPath("LeftColumnWidth"),
            Mode = BindingMode.OneWay,
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
        };
        HandleLeftTop.SetBinding(WidthProperty, leftColumnWidthbindingElement);

    // same for right and middle column           

        _viewModel.Expanded = false;

    }
}

public class RTGraphControlViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    private readonly RTGraphControl _rt;
    private bool _expanded;
    private double _rowHeight;
    private double _leftcolumnWidth;
    private double _middlecolumnWidth;
    private double _rightcolumnWidth;

    public RTGraphControlViewModel(RTGraphControl rt)
    {
        _rt = rt;
    }

    public bool Expanded
    {
        get { return _expanded; }
        set
        {
            _expanded = value;
            double width = _rt.MainGrid.ActualWidth;
            if (_expanded)
            {
                LeftColumnWidth = width*0.2;
                RightColumnwidth = width*0.2;
                MiddleColumnWidth = width*0.6;
            }
            else
            {
                LeftColumnWidth = width * 0.5;
                RightColumnwidth = width * 0.5;
                MiddleColumnWidth = width * 0;
            }
            OnPropertyChanged("Expanded");
        }
    }

    public double LeftColumnWidth
    {
        get { return _leftcolumnWidth; }
        set
        {
            _leftcolumnWidth = value;
            OnPropertyChanged("LeftColumnWidth");
        }
    }

    public double MiddleColumnWidth {...}

    public double RightColumnwidth {...}

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

      

This kind of works for the left and middle columns, but funny enough it doesn't work for the right column. The right column does not change its width at all. Another issue is that after initializing the actual user control width is set to 0. The workaround with .Measure and .Arrange did not work.

Thank you in advance

John

+3


source to share


1 answer


You can define your XAML like this:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>

    <Grid Grid.Column="0" Grid.Row="0" Background="ForestGreen" Margin="2"
          MouseDown="OuterContainer_OnMouseDown" />
    <Grid Grid.Column="2" Grid.Row="0" Background="LimeGreen" Margin="2"
          MouseDown="OuterContainer_OnMouseDown" />
    <Grid Grid.Column="0" Grid.Row="1" Background="Firebrick" Margin="2"
          MouseDown="OuterContainer_OnMouseDown" />
    <Grid Grid.Column="2" Grid.Row="1" Background="OrangeRed" Margin="2"
          MouseDown="OuterContainer_OnMouseDown" />

    <Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Background="DodgerBlue"
          MouseDown="MiddleContainer_OnMouseDown" x:Name="MiddleContainer"
          Visibility="Collapsed" Width="300" Margin="2" />
</Grid>

      

Then some code to show / hide the middle drawer:

private void OuterContainer_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    MiddleContainer.Visibility = Visibility.Visible;
}

private void MiddleContainer_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    MiddleContainer.Visibility = Visibility.Collapsed;
}

      

Hidden:



middle box hidden

Shown:

middle box showing

The only caveat is that the average drawer has a given size (300, but you can change it) instead of 60%. Not sure what you are going to do with it so it might or might not be a problem.

+4


source







All Articles