Если вы используете DependencyPropertyHelper.GetValueSource (Rowdefinition.HeightProperty), вы можете видеть, что изначально значение свойства задается стилем, но после того, как GridSplitter изменит высоту строки, свойство height имеет «локальное» значение. Локальные значения имеют приоритет над всеми другими источниками для значения зависимости, поэтому, когда триггер данных пытается установить свойство height в 0, ничего не происходит.
В дополнение к этому, GridSplitter устанавливает высоту над ним над строкой, и как только будут задействованы относительные значения (звезды), набор высоты выглядит несколько недружелюбным.
Вот как я нашел, чтобы работать вокруг этой проблемы:
скрытие строки очистить значение свойства высоты, прежде чем пытаться установить высоту до 0
И
при отображении строки видно значение свойства высоты верхней строки для сброса высоты до ее начального значения.
Этот второй шаг вызвал у меня самую большую головную боль. Например, «недружественные» значения высоты, установленные 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));
}
}
}
Надеется, что это поможет вам, если вы еще не нашли другое решение.
Спасибо за обмен – user1135594