WPF布局绑定

3
我很抱歉这篇文章有点长,但这件事让我感到沮丧已经持续了两天。请看下面的图片。当鼠标点击1-4中的任意一个块时,这些块会调整大小并且中间出现一个大块5。再次单击鼠标可逆转此过程。 Resizing Tiles 首先,我尝试直接绑定行列定义的宽度/高度属性,但完全不起作用。当前的解决方案是使用标签的宽度和高度属性来完成缩放。代码如下...
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>

C#:

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));
    }
}

这适用于左列和中列,但有趣的是对于右列却不行。右列根本不改变其宽度。另一个问题是,在用户控件初始化后,实际宽度被设置为0。使用.Measure和.Arrange的解决方法没有起作用。
提前感谢您
Jon

我本来想建议使用自定义的“Panel”,但显然那行不通 :( - BradleyDotNET
1个回答

4
您可以像这样定义您的XAML:

您可以像这样定义您的XAML:

<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>

接下来需要一些代码来显示/隐藏中间的框:

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

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

隐藏:

中间框隐藏

显示:

中间框显示

唯一的注意事项是中间框有一个预设大小(300,但您可以更改),而不是60%。不确定您打算如何使用它,因此可能会或可能不会成为问题。


非常感谢。这个解决方案很简单,但是经过一些微调可以满足预期。 - JonBlumfeld

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接