如果您使用 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));
}
}
}
如果您还没有找到其他解决方案,希望这对您有所帮助。