我有一个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>
我对此没有任何想法,有人能给我一个暗示吗?感谢
答案 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));
}
}
}
希望如果您还没有找到其他解决方案,这会对您有所帮助。