gpt4 book ai didi

c# - Canvas ActualWidth 和 ActualHeight 以 MVVM 方式传入 ViewModel

转载 作者:行者123 更新时间:2023-12-03 10:31:10 24 4
gpt4 key购买 nike

最近我遇到了一个看似简单的问题:我想在我正在处理的一个应用程序中使用 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。
我的问题是:您是否建议对我的代码进行任何改进(例如与可能的内存泄漏等有关)?我只想在学习新东西的同时“MinMax”。我是一名初级开发人员,我不能真正向 IRL 咨询这个问题,因为我认识的人都没有 MVVM。我正在尝试以模块化方式编写所有内容,这意味着我想编写一次,然后在我再次需要它时复制它,以加快我开发应用程序的速度。
期待您的建议。

最佳答案

我对这个问题的解决方案是一组附加属性,它们可以应用于任何 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com