2014-10-31 6 views
3

Приносим извинения за длину этого сообщения, но этот изгоняет меня в течение двух дней прямо сейчас. Рассмотрим изображение ниже. На Mouseclick на одной из плиток 1-4 размер плитки и большая плитка 5 появляются посередине. Другой mouseclick отменяет процесс. Resizing TilesWPF Layout Binding

Сначала я попытался напрямую связать свойство width/height в строках и столбцах. Это не сработало. В текущем решении используется свойство width и height для меток, чтобы получить изменение размера. Код выглядит следующим образом ...

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

Этот вид работ для левой и средней колонке, но достаточно странно, что Безразлично» t для правой колонки. Правая колонка вообще не меняет свою ширину. Другая проблема заключается в том, что после инициализации фактической ширины пользовательского контроля установлено значение 0. Обходной путь с .Measure и .Arrange не работает.

Заранее спасибо

Jon

+0

Я собирался предложить пользовательскую 'Панель', но, видимо, это не сработало :( – BradleyDotNET

ответ

4

Вы можете определить свой 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; 
} 

Скрывало:

middle box hidden

Показаны:

middle box showing

Единственное ограничение в том, что средний блок имеет предустановленный размер (300, но вы можете изменить это), а не 60%. Не уверен, что вы намереваетесь сделать с ним, чтобы это могло быть или не быть проблемой.

+0

Большое спасибо. Довольно простое решение, но работает по назначению с некоторыми настройками. – JonBlumfeld