我正在设计一个用户控件,它需要是方形的,并填充给定的尽可能多的空间(为了提供一些上下文,它是一个棋盘)。
我的用户控件如下所示:
<Grid>
<!-- My 8 lines / colums, etc. , sized with "1*" to have equal lines -->
</Grid>
现在我只想说“无论它要扩展什么空间,这个网格都必须是正方形的”。
尝试了徒劳的解决方案:
我无法使用
UniformGrid
,因为我实际上还有行和列的名称,因此我有一个不同大小的前导标题行和列。如果我将
Viewbox
与Uniform
结合使用,一切都会变得困惑。我尝试使用经典
<Grid Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}"> ... </Grid>
但只有当我手动设置 Width
属性时它才有效。否则,该约束将被忽略。
结论
我不知道,我真的很想避免手动设置 Width
/Height
,因为此控件可能会在许多不同的地方使用( ListItem
模板、游戏等...)。
建议的解决方案:
有一些隐藏代码的解决方案。我没有找到仅 XAML 的解决方案。
网格现在是:
<Grid SizeChanged="Board_FullControlSizeChanged">...</Grid>
事件处理程序是:
private void Board_FullControlSizeChanged(object sender, SizeChangedEventArgs args)
{
double size = Math.min (args.NewSize.Height, args.NewSize.Width);
((Grid)sender).Width = size;
((Grid)sender).Height = size;
}
最佳答案
我最初尝试修改对 ActualWidth
的绑定(bind),但当 Grid
是顶级元素时它仍然不起作用,并且在某些情况下最终会进一步扩展控件比可用尺寸。因此尝试了一些其他方法来获取所需的输出。
有两种方法可以解决这个问题:
因为这是一个与 View 相关的问题(不破坏 MVVM,保持方形结构,如果你同意有一些代码隐藏,你可以做类似的事情)
private void OnSizeChanged(object sender, SizeChangedEventArgs e) {
double minNewSizeOfParentUserControl = Math.Min(e.NewSize.Height, e.NewSize.Width);
mainGrid.Width = minNewSizeOfParentUserControl;
mainGrid.Height = minNewSizeOfParentUserControl;
}
在您的 xaml 中,您可以将主顶级网格命名为“mainGrid”,并将 UserControl
大小更改事件处理程序附加到上述函数而不是 Grid
本身。
但是,如果您出于某种原因完全讨厌代码隐藏,您可以更花哨一点并创建诸如
public class GridSquareSizeBehavior : Behavior<Grid> {
private UserControl _parent;
protected override void OnAttached() {
DependencyObject ucParent = AssociatedObject.Parent;
while (!(ucParent is UserControl)) {
ucParent = LogicalTreeHelper.GetParent(ucParent);
}
_parent = ucParent as UserControl;
_parent.SizeChanged += SizeChangedHandler;
base.OnAttached();
}
protected override void OnDetaching() {
_parent.SizeChanged -= SizeChangedHandler;
base.OnDetaching();
}
private void SizeChangedHandler(object sender, SizeChangedEventArgs e) {
double minNewSizeOfParentUserControl = Math.Min(e.NewSize.Height, e.NewSize.Width);
AssociatedObject.Width = minNewSizeOfParentUserControl;
AssociatedObject.Height = minNewSizeOfParentUserControl;
}
}
对于您的 xaml 的行为,如下所示:
<Grid>
<i:Interaction.Behaviors>
<local:GridSquareSizeBehavior />
</i:Interaction.Behaviors>
</Grid>
是否使用 Snoop 测试了这两种方法,并且在扩展/收缩时保持了正方形大小。请注意,关键中的两种方法都使用相同的逻辑(只是一个快速模型),如果您将逻辑更新为仅在宽度更改时更新高度,反之亦然,而不是同时更新并取消,您可能能够获得更好的性能如果不需要,可以一起调整大小
关于wpf - 创建一个方形用户控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15603096/