GridSplitter禁用我的RowDefinition样式

时间:2013-08-14 14:44:34

标签: c# wpf grid gridsplitter

我有一个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>

我还有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"/>

这样做的目的是当我点击Checkbox时出现最后一行并占据第二行的35%,但我可以使用GridSplitter调整其大小。取消选中Checkbox时,该行的可见性为Collapsed

问题在于,如果我使用GridSplitter新高度似乎覆盖初始样式定义,当我取消选中Checkbox时,最后一行仍然可见。< / p>

我对此没有任何想法,有人能给我一个暗示吗?感谢

1 个答案:

答案 0 :(得分:4)

如果使用DependencyPropertyHelper.GetValueSource(Rowdefinition.HeightProperty),您可以看到最初属性值是由样式设置的,但是在GridSplitter更改行的高度后,height属性具有&#34; local&#34 ;值。本地值优先于依赖项值的所有其他源,因此当数据触发器尝试将height属性设置为0时,没有任何事情发生。

除此之外,GridSplitter设置它上面的行的高度,一旦涉及相对(星)值,设置的高度看起来有点不友好。

以下是我找到解决此问题的方法:

隐藏行时,在尝试将高度设置为0之前清除height属性的值

使行可见时清除上行高度属性的值,将高度重置为初始值。

这第二步让我头痛不已。 &#34;不友好&#34;例如,GridSplitter设置的高度值可以是181.7634545 *。如果你想再次显示底行并给它一个0.35 *的高度,看起来它没有被显示,因为它只有几个像素高!

不幸的是,我还没有找到一种在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:

using System.Windows;

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

        public MainWindow()
        {
            InitializeComponent();

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

最后是视图模型。重要的一点是方法ResetHeight()和调用该方法的属性IsRowVisible

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

希望如果您还没有找到其他解决方案,这会对您有所帮助。