我的目标是保存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像素)。
为什么会发生这种情况,你会怎么做?
答案 0 :(得分:3)
<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
上的模板来完成的,这些模板是拆分控制模板的子项。