2

我有一个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的最后一行时仍然可见。

我对此没有任何想法,有人可以给我提示吗?谢谢

4

1 回答 1

4

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

最重要的是,GridSplitter 设置其上方行的高度,一旦涉及相对(星形)值,设置的高度看起来有点不友好。

这是我发现解决此问题的方法:

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

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

这第二步让我最头疼。例如,由 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>

主窗口.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));
        }
    }
}

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

于 2013-09-27T15:51:24.830 回答