Почему эта привязка данных не меняет GridUnitType?
Моя цель - сохранить GridSplitter
положение для последующего отзыва. Сплиттер находится внутри Grid
элемент управления с тремя столбцами, определенными следующим образом:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding GridPanelWidth, Mode=TwoWay}" />
<ColumnDefinition Width="3" /> <!--splitter itself is in this column-->
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
Недвижимость GridPanelWidth
определяется таким образом в модели представления:
private GridLength _gridPanelWidth = new GridLength(1, GridUnitType.Star);
public GridLength GridPanelWidth
{
get { return _gridPanelWidth; }
set
{
if (_gridPanelWidth != value)
SetProperty(ref _gridPanelWidth, value, () => GridPanelWidth);
}
}
Проблема у меня заключается в том, что при перемещении сплиттера привязка обновляет только Double
(Значение) компонент связанного свойства, но не GridUnitType
Часть этого.
Пример: свойство по умолчанию имеет значение 1*
, Пользователь перетаскивает разделитель, и значение становится 354*
вместо просто 354
, При восстановлении значения оно становится огромным (354 раза, а не 354 пикселя).
Почему это происходит, и что бы вы сделали с этим?
1 ответ
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding GridPanelWidth, Mode=TwoWay}" />
<ColumnDefinition Width="4" />
<!--splitter itself is in this column-->
<ColumnDefinition x:Name="RightColumn" Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
BorderBrush="Gray"
BorderThickness="1"
Grid.Column="0"
Grid.Row="0"
/>
<GridSplitter
Background="SteelBlue"
ResizeBehavior="PreviousAndNext"
ResizeDirection="Columns"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ShowsPreview="False"
Grid.Column="1"
Grid.Row="0"
/>
<Border
BorderBrush="Gray"
BorderThickness="1"
Grid.Column="2"
Grid.Row="0"
/>
<StackPanel
Grid.Row="1"
Grid.ColumnSpan="3"
Grid.Column="0"
>
<TextBlock>
<Run>GridPanelWidth: </Run>
<Run Text="{Binding GridPanelWidth.Value, Mode=OneWay}" />
<Run Text="{Binding GridPanelWidth.GridUnitType, Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run>RightColumn.Width: </Run>
<Run Text="{Binding Width.Value, ElementName=RightColumn, Mode=OneWay}" />
<Run Text="{Binding Width.GridUnitType, ElementName=RightColumn, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</Grid>
Снимок экрана 1:
Снимок экрана 2:
Снимок экрана 3:
Res ipsa loquitor, насколько я понимаю, но просто чтобы быть в безопасности:
Поскольку родительский размер может быть изменен, разделитель сетки изменяет соотношение между двумя столбцами, сохраняя при этом GridUnitType.Star
для каждого из них, так что при изменении размера родителя отношение, естественно, останется постоянным. Это сохраняет намерение начальных значений ширины в XAML.
Width.Value
для левой колонки оказывается идентичной левой границе ActualWidth
и то же самое верно для правого столбца. Вам придется взять оба и сохранить соотношение.
Обновить
я нахожу Grid
/GridSplitter
немного перегружен для повседневного использования, когда все, что я хочу, это еще одна панель навигации, поэтому я недавно написал SplitterControl
он имеет два свойства содержимого и устанавливает сетку и разделитель со стилем в шаблоне. Я не удосужился сделать постоянный коэффициент разделения, поэтому я сделал это только сейчас.
То, что я сделал, было довольно болезненным, потому что элемент управления настраиваемый, а код не так уж и хорош, но я могу поделиться, если вам интересно.
Конец бизнеса прост:
Когда размер столбца изменяется, установите флаг, чтобы заблокировать рекурсию и
PaneRatio = _PART_ContentColumn.Width.Value / _PART_NavColumn.Width.Value;
когда PaneRatio
изменяется, если он не был установлен обработчиком изменения размера столбца
_PART_NavColumn.Width = new GridLength(1, GridUnitType.Star);
_PART_ContentColumn.Width = new GridLength(PaneRatio, GridUnitType.Star);
На практике столбцы навигатора / содержимого можно менять местами или вместо этого они могут быть строками. Оба из них сделаны путем переключения шаблонов на HeaderedContentControl
это дочерний элемент шаблона управления разделением.