简体   繁体   English

GridSplitter禁用我的RowDefinition样式

[英]GridSplitter disables my RowDefinition style

I have a Grid that contains three rows, and the third row visibility is bound to a boolean: 我有一个包含三行的Grid ,第三行的可见性绑定到一个布尔值:

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="120"/>
        <RowDefinition Height="*" />
        <RowDefinition>
            <RowDefinition.Style>
                <Style TargetType="{x:Type RowDefinition}">
                    <Setter Property="Height"
              Value="0.35*" />
                    <Style.Triggers>
                       <DataTrigger Binding="{Binding ElementName=plotter2, Path=Visibility}" Value="Collapsed">
                            <Setter Property="Height"  Value="0" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RowDefinition.Style>
        </RowDefinition>

I also have a GridSplitter : 我也有一个GridSplitter

 <GridSplitter
                ResizeDirection="Rows"
                ResizeBehavior="BasedOnAlignment"
                Grid.Column="0"
                Grid.ColumnSpan="2"
                Grid.Row="2"             
                Width="Auto"
                Height="6"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Top"
                Margin="0 20 0 0"
                Background="Transparent"/>

The purpose of this is that when I click a Checkbox the last row appears and occupy 35% of the second, but I can resize it with the GridSplitter . 这样做的目的是,当我单击一个Checkbox将显示最后一行并占据第二行的35%,但是我可以使用GridSplitter调整其大小。 When the Checkbox is unchecked that row's visibility is Collapsed . 取消选中Checkbox ,该行的可见性为Collapsed

The problem is that if I use the GridSplitter the new height seems to overwrite the initial style definition and when I uncheck my Checkbox the last row remains visible. 问题是,如果使用GridSplitter则新高度似乎会覆盖初始样式定义,并且当我取消选中Checkbox ,最后一行仍然可见。

I don't have any idea to some this, could anyone give me a hint? 我对此一无所知,有人可以给我提示吗? Thanks 谢谢

If you use DependencyPropertyHelper.GetValueSource(Rowdefinition.HeightProperty) you can see that initially the property value is set by the style, but after the GridSplitter changes the height of the row the height property has a "local" value. 如果使用DependencyPropertyHelper.GetValueSource(Rowdefinition.HeightProperty),则可以看到最初由样式设置属性值,但是在GridSplitter更改行的高度后,height属性具有“局部”值。 Local values take precedence over all other sources for a dependency value, so when the data trigger attempts to set the height property to 0 nothing happens. 对于依赖项值,本地值优先于所有其他源,因此,当数据触发器尝试将height属性设置为0时,什么都不会发生。

On top of this, the GridSplitter sets the height of the row above it and as soon as relative (star) values are involved the heights set look somewhat unfriendly. 最重要的是,GridSplitter设置了其上方行的高度,并且一旦涉及到相对(星号)值,该高度设置就显得有些不友好了。

Here is the way I found to work round this problem: 这是我发现解决此问题的方法:

when hiding the row clear the value of the height property before attempting to set the height to 0 隐藏行时,在尝试将height设置为0之前,请清除height属性的值

AND

when making the row visible clear the value of the height property of the upper row to reset the height to its initial value. 当使该行可见时,清除上一行的height属性的值,以将高度重置为其初始值。

This second step caused me the biggest headache. 第二步使我感到最大的头痛。 The "unfriendly" height values set by the GridSplitter can be 181.7634545* for example. 例如,由GridSplitter设置的“不友好”高度值可以是181.7634545 *。 If you want to show the bottom row again and you give it a height of 0.35* it looks like it's not being made visible as it's only a couple of pixels high! 如果您想再次显示底部的行,并将其高度设置为0.35 *,则看起来好像没有被看到,因为它只有几个像素高!

Unfortunately I haven't found a way to do this all in XAML. 不幸的是,我还没有找到在XAML中完成所有这些操作的方法。 The solution relies on programmatically resetting the two affected rows heights at the appropriate moment. 该解决方案依赖于在适当的时刻以编程方式重置两个受影响的行的高度。

In case the text isn't quite clear here's the code I used to test this: 如果文字不太清楚,这是我用来测试的代码:

MainWindow.cs.xaml: MainWindow.cs.xaml:

<Window x:Class="GridRowHidingSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="120" />
        <RowDefinition Name="TopRow" />
        <RowDefinition Name="BottomRow">
            <RowDefinition.Style>
                <Style TargetType="{x:Type RowDefinition}">
                    <Setter Property="Height" Value="0.35*" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsRowVisible, Mode=OneWay}" Value="False">
                            <Setter Property="Height"  Value="0" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RowDefinition.Style>
        </RowDefinition>
    </Grid.RowDefinitions>
    <Border Background="Yellow">
        <CheckBox Content="Show bottom row" HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="{Binding Path=IsRowVisible, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10" />
    </Border>
    <Border Background="Red" Grid.Row="1">
    </Border>
    <Border Grid.Row="2" Background="Green">
    </Border>
    <GridSplitter Grid.Row="2" Height="10" HorizontalAlignment="Stretch" VerticalAlignment="Top" Background="DarkGray" Margin="0,20,0,0" />
</Grid>

MainWindow.cs: MainWindow.cs:

using System.Windows;

namespace GridRowHidingSample
{
    public partial class MainWindow : Window
    {
        private MainWindowViewModel _viewModel;

        public MainWindow()
        {
            InitializeComponent();

            _viewModel = new MainWindowViewModel(TopRow, BottomRow);
            DataContext = _viewModel;
        }
    }
}

And finally the view model. 最后是视图模型。 The important bit is the method ResetHeight() and the Property IsRowVisible where the method is called. 重要的一点是方法ResetHeight()和调用该方法的属性IsRowVisible

MainWindowViewModel.cs: MainWindowViewModel.cs:

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace GridRowHidingSample
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private RowDefinition _topRow;
        private RowDefinition _bottomRow;
        private bool _isRowVisible = false;

        public MainWindowViewModel(RowDefinition topRow, RowDefinition bottomRow)
        {
            _topRow = topRow;
            _bottomRow = bottomRow;
        }

        private void ResetHeight(RowDefinition rowDefinition)
        {
            if (rowDefinition != null)
            {
                if (DependencyPropertyHelper.GetValueSource(rowDefinition, RowDefinition.HeightProperty).BaseValueSource == BaseValueSource.Local)
                rowDefinition.ClearValue(RowDefinition.HeightProperty);
            }
        }

        public bool IsRowVisible
        {
            get { return _isRowVisible; }
            set
            {
                if (_isRowVisible != value)
                {
                    _isRowVisible = value;
                    NotifyPropertyChanged("IsRowVisible");

                    if (_isRowVisible)
                        ResetHeight(_topRow);
                    else
                        ResetHeight(_bottomRow);
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Hope this helps you, if you haven't already found another solution. 如果您还没有找到其他解决方案,希望对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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