当网格 (usercontrol/window) 大小改变时,带有固定面板(网格列)的 GridSplitter
GridSplitter with a fixed panel (grid column) when grid (usercontrol/window) size changes
基本上,我想模拟 WinForms
中可用的 GridSplitter.FixedPanel
功能。
XAML :
<UserControl ...>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0" />
<GridSplitter
Grid.Column="1" Width="3" VerticalAlignment="Stretch"
Background="Transparent"
ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" />
<ListBox Grid.Column="2" />
</Grid>
</UserControl>
这很好用,可以相应地调整每一边的大小。但是假设我们调整包含此 UserControl 的(未最大化)window 的大小,现在拆分器(自动)两侧的两个网格列都会调整大小。开始时 space 分配需要 4/5 和 1/5 的列宽比,但实际 space 分配取决于显示的数据,因此网格拆分器。
如何使一列保持其宽度(例如右侧的一列,因为它包含属性、工具等)而 window 调整大小,因此只调整左列的大小。
我有一些想法:
- 只需隐藏代码即可像在 WinForms 中一样模拟 FixedPanel:DragStarted、DragCompleted 和一些私有字段,例如
- 像 SO topic 中建议的那样使用
Behavior
(我已经很多年没有使用行为了,需要做一些令人耳目一新的事情 - 老实说,我真的希望有一个 XAML-唯一的方式,但如果没有,我更喜欢我公开新的依赖属性而不是行为的代码隐藏方式)
- 我相信我缺少 WPF 的一项功能来实现此 WPF 方式。几乎所有时候我都在想 “嗯,我想我必须 代码背后 这个...”,有 WPF 方式,通常更简单,更安全,易于设计,性能更好。这就是我直接询问的原因,也许会帮助其他人寻找该功能。
编程语言(就此而言):C#
编辑:在 Léo Savador 的回答之后:
请参阅:有 WPF 方式(玩弄 XAML ColumnDefinition
Width
属性)和少量代码:
bool p_layoutInitialized = false;
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 1) { // optional : && e.NewSize.Height > 1
if (!p_layoutInitialized) {
RightColumn.Width = new GridLength(MainGrid.ActualWidth / 5);
p_layoutInitialized = true;
}
}
}
其中 RightColumn
是右侧 ColumnDefinition
的名称,MainGrid
是 Grid
.
的名称
非常感谢,正在后面写重代码。你节省了我很多时间 :D
PS : 请不要假设我是 WinForm 迷。我只是提到 WinForms 来给出所需功能的比较示例,可以使用 CSS 和 JS,但更难描述。
这里有一个简单的解决方案,我可以根据您的需要推荐给您:
对于您的右栏,不要使用动态宽度 (1*),而是使用固定宽度:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="160" />
</Grid.ColumnDefinitions>
如果您将固定宽度设置为 160:
- 您将获得相同的初始结果(window 初始宽度的 1/5)
- 您仍然可以调整网格大小
- 调整大小时,右栏将保持其宽度
而且你也有可能在启动时使用代码隐藏来计算所需的固定宽度,根据window初始宽度,更“动态”。
基本上,我想模拟 WinForms
中可用的 GridSplitter.FixedPanel
功能。
XAML :
<UserControl ...>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0" />
<GridSplitter
Grid.Column="1" Width="3" VerticalAlignment="Stretch"
Background="Transparent"
ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" />
<ListBox Grid.Column="2" />
</Grid>
</UserControl>
这很好用,可以相应地调整每一边的大小。但是假设我们调整包含此 UserControl 的(未最大化)window 的大小,现在拆分器(自动)两侧的两个网格列都会调整大小。开始时 space 分配需要 4/5 和 1/5 的列宽比,但实际 space 分配取决于显示的数据,因此网格拆分器。
如何使一列保持其宽度(例如右侧的一列,因为它包含属性、工具等)而 window 调整大小,因此只调整左列的大小。
我有一些想法:
- 只需隐藏代码即可像在 WinForms 中一样模拟 FixedPanel:DragStarted、DragCompleted 和一些私有字段,例如
- 像 SO topic 中建议的那样使用
Behavior
(我已经很多年没有使用行为了,需要做一些令人耳目一新的事情 - 老实说,我真的希望有一个 XAML-唯一的方式,但如果没有,我更喜欢我公开新的依赖属性而不是行为的代码隐藏方式) - 我相信我缺少 WPF 的一项功能来实现此 WPF 方式。几乎所有时候我都在想 “嗯,我想我必须 代码背后 这个...”,有 WPF 方式,通常更简单,更安全,易于设计,性能更好。这就是我直接询问的原因,也许会帮助其他人寻找该功能。
编程语言(就此而言):C#
编辑:在 Léo Savador 的回答之后:
请参阅:有 WPF 方式(玩弄 XAML ColumnDefinition
Width
属性)和少量代码:
bool p_layoutInitialized = false;
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 1) { // optional : && e.NewSize.Height > 1
if (!p_layoutInitialized) {
RightColumn.Width = new GridLength(MainGrid.ActualWidth / 5);
p_layoutInitialized = true;
}
}
}
其中 RightColumn
是右侧 ColumnDefinition
的名称,MainGrid
是 Grid
.
非常感谢,正在后面写重代码。你节省了我很多时间 :D
PS : 请不要假设我是 WinForm 迷。我只是提到 WinForms 来给出所需功能的比较示例,可以使用 CSS 和 JS,但更难描述。
这里有一个简单的解决方案,我可以根据您的需要推荐给您:
对于您的右栏,不要使用动态宽度 (1*),而是使用固定宽度:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="160" />
</Grid.ColumnDefinitions>
如果您将固定宽度设置为 160:
- 您将获得相同的初始结果(window 初始宽度的 1/5)
- 您仍然可以调整网格大小
- 调整大小时,右栏将保持其宽度
而且你也有可能在启动时使用代码隐藏来计算所需的固定宽度,根据window初始宽度,更“动态”。