- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近我遇到了一个看似简单的问题:我想在我正在处理的一个应用程序中使用 Mode=OneWayToSource 将 Canvas 的 Width 和 Height 参数推送到 ViewModel 中。原来 Mode=OneWayToSource 对此不起作用,根据微软的说法,这是 WPF 的一个功能。好的。
无论如何,一段时间以来我一直在想如何在遵守 MVVM 原则的同时以最好的方式(即最短和最不困惑)做到这一点。我想出了以下几点:
/// <summary>
/// Sends graph dimensions to <see cref="GraphViewModel"/>
/// </summary>
public class SendGraphDimensionsToViewModelProperty : BaseAttachedProperty<SendGraphDimensionsToViewModelProperty, bool>
{
public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (!(sender is Canvas canvas))
return;
canvas.SizeChanged += (sender, e) =>
{
if (canvas.DataContext is GraphViewModel graph)
{
graph.Width = canvas.ActualWidth;
graph.Height = canvas.ActualHeight;
}
};
}
}
然后我只是将属性附加到带有 GraphViewModel 实例的 DataContext 的 Canvas 上:
local:SendGraphDimensionsToViewModelProperty.Value="True"
这按预期工作。 基本上,附加属性的值在加载时从 null 更改为 true,这会触发 SizeChanged 事件,该事件监视 Canvas 的 ActualHeight 和 ActualWidth。
最佳答案
我对这个问题的解决方案是一组附加属性,它们可以应用于任何 FrameworkElement 实例。
public static class perSizeBindingHelper
{
public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
"Active",
typeof(bool),
typeof(perSizeBindingHelper),
new FrameworkPropertyMetadata(OnActiveChanged));
public static bool GetActive(FrameworkElement frameworkElement)
{
return (bool) frameworkElement.GetValue(ActiveProperty);
}
public static void SetActive(FrameworkElement frameworkElement, bool active)
{
frameworkElement.SetValue(ActiveProperty, active);
}
public static readonly DependencyProperty BoundActualWidthProperty = DependencyProperty.RegisterAttached(
"BoundActualWidth",
typeof(double),
typeof(perSizeBindingHelper));
public static double GetBoundActualWidth(FrameworkElement frameworkElement)
{
return (double) frameworkElement.GetValue(BoundActualWidthProperty);
}
public static void SetBoundActualWidth(FrameworkElement frameworkElement, double width)
{
frameworkElement.SetValue(BoundActualWidthProperty, width);
}
public static readonly DependencyProperty BoundActualHeightProperty = DependencyProperty.RegisterAttached(
"BoundActualHeight",
typeof(double),
typeof(perSizeBindingHelper));
public static double GetBoundActualHeight(FrameworkElement frameworkElement)
{
return (double) frameworkElement.GetValue(BoundActualHeightProperty);
}
public static void SetBoundActualHeight(FrameworkElement frameworkElement, double height)
{
frameworkElement.SetValue(BoundActualHeightProperty, height);
}
private static void OnActiveChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
if (!(dependencyObject is FrameworkElement frameworkElement))
{
return;
}
if ((bool) e.NewValue)
{
frameworkElement.SizeChanged += OnFrameworkElementSizeChanged;
UpdateObservedSizesForFrameworkElement(frameworkElement);
}
else
{
frameworkElement.SizeChanged -= OnFrameworkElementSizeChanged;
}
}
private static void OnFrameworkElementSizeChanged(object sender, SizeChangedEventArgs e)
{
if (sender is FrameworkElement frameworkElement)
{
UpdateObservedSizesForFrameworkElement(frameworkElement);
}
}
private static void UpdateObservedSizesForFrameworkElement(FrameworkElement frameworkElement)
{
frameworkElement.SetCurrentValue(BoundActualWidthProperty, frameworkElement.ActualWidth);
frameworkElement.SetCurrentValue(BoundActualHeightProperty, frameworkElement.ActualHeight);
}
}
用法是...
<Grid ...
vhelp:perSizeBindingHelper.Active="True"
vhelp:perSizeBindingHelper.BoundActualHeight="{Binding GridHeight, Mode=OneWayToSource}"
vhelp:perSizeBindingHelper.BoundActualWidth="{Binding GridWidth, Mode=OneWayToSource}">
关于c# - Canvas ActualWidth 和 ActualHeight 以 MVVM 方式传入 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63860555/
我正在尝试在窗口显示之前计算 StackPanel width, height(位于网格的中间单元格)(例如窗口构造函数)。如何实现?
如何向用户公开我的用户控件组件之一的 ActualWidth 属性? 我找到了很多关于如何通过创建新的依赖属性和绑定(bind)来公开普通属性的示例,但没有关于如何公开像 ActualWidth 这样
为什么我不能引用ActualWidth作为一个值,我可以在代码中使用它。 XAML:
考虑以下简单代码: XAML: MouseDoubleClick 事件: private void TextBox_Mo
我花了几个小时看这个没有结果。 我只是想要一个DataGrid X 列保持与 Grid 的相对宽度本身。 因此,例如: 第 1 栏:10% 第 2 栏:10% 第 3 栏:10% 我设置了一个附加到
在 Silverlight 3.0 应用程序中,我试图在 Canvas 中创建一个矩形并让它拉伸(stretch) Canvas 的整个宽度。我试图通过绑定(bind)到 ActualWidth 来做
我无法将 Canvas 的 ActualWidth 设为任何非零值。我简化了真实场景,并在 VS 中专门创建了一个新的 WPF 应用程序来获取非零值(和理解)。不幸的是,我只得到零。我觉得我缺少一些基
我有一个带有 TextBlock 的 Canvas,如下所示: 我
我刚刚用 C# 编写了一个在我的桌面上显示引号的小程序。我的问题是将应用程序的窗口居中。要计算窗口的所需位置,我使用以下公式: Left = (Screen.PrimaryScreen
所以我读过 ActualWidth可能等于 0,直到它完全加载。我像这样添加了它的事件处理程序,以确保它已完全加载: text.AddHandler(TextBlock.LoadedEvent, ne
我需要一个 Viewport3D仅用于使用 Petzold.Media3D.ViewportInfo 进行几何计算.我宁愿不必将它放在 Window 中。或以其他方式呈现它。 我试图通过实例化 Vie
将此粘贴到苹果酒中。 现在,运行它。第二个TextBlock显示 0,但不应该,对吧?解决方法? 最佳
我想将 WPF 路径添加到 InkCanvas并使用选择来选择 WPF 路径。 所以,我使用这个代码。 System.Windows.Shapes.Path path = drawCanvas.Chi
最近我遇到了一个看似简单的问题:我想在我正在处理的一个应用程序中使用 Mode=OneWayToSource 将 Canvas 的 Width 和 Height 参数推送到 ViewModel 中。原
我在 Canvas 中有一个 Grid ,定义如下:
我正在为 Windows Phone 7 创建一个照片库,我试图让每张图片全屏显示并水平滑动。到目前为止我正在做的是使用我修改过的列表框来水平滚动,但问题是我似乎无法找到一种方法将 ListboxIt
我试图解决我以前的question手动绑定(bind)Width DataGridTextColumn 的属性(property)这是我的 XAML 代码的第一个版本。
这个问题在这里已经有了答案: Pushing read-only GUI properties back into ViewModel (6 个答案) 关闭 8 年前。 我想将控件的只读属性绑定(b
我是一名优秀的程序员,十分优秀!