gpt4 book ai didi

c# - 在 Viewmodel 属性中防止 StackOverFlow 或递归

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

我坚持实现“保持纵横比”功能。
假设您向上/向下旋转宽度控件。它直接计算对应于 w/h 比率的高度,反之亦然。由于此窗口在代码后面有两个 valueChanged 事件。每次值改变时,它都会调用它的相反事件。

enter image description here

我为递归调用编写了一个防止代码。

    private void OnChangedPixelWValue(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (JustHModified)
{
return;
}

if (VM.IsKeepAspectRatio)
{
double DesiredHeight = VM.ImageSizeX / RatioWH;
JustHModified = true;
VM.ImageSizeY = (int)DesiredHeight;
JustHModified = false;
}
}
// ... Same logic exists (OnChangedPixelHValue)

每个 VM 属性都使用 Mode Oneway 绑定(bind)到 UI。这是 ViewModel 中的属性代码。
    private int m_ImageSizeY;
public int ImageSizeY
{
get { return m_ImageSizeY; }
set { m_ImageSizeY = value;
OnPropertyChanged("ImageSizeY");
}
}
// ... ImageSizeX exists too

事件函数代码看起来很脏,但我正在尝试各种方法来防止它。
也许我不完全理解 MVVM 逻辑或遗漏了一些东西。
像下面这样调用堆栈
1. OnChangedPixelWValue function called
2. ViewModel ImageSizeY property-setter called
3. OnPropertyChanged(string propertyName) function called
4. OnChangedPixelHValue function called
...

这是我研究过的其他问题,但对我没有帮助。

Preventing StackOverFlow in recursive functions

How to avoid property recursion

How to prevent recursion

最佳答案

正确的解决方案需要您实现命令而不是使用事件。
事件是纯粹的 UI 事物,因此不应(在所有好的情况下)在 ViewModel 上处理

考虑一个场景,您想要插入另一个不触发任何事件的控件,然后您的代码将无法工作。

处理这种情况的另一种更好的方法是将你的属性与这些控件绑定(bind),一旦你改变了高度,它应该更新宽度的局部变量并调用NotifyProeprtyChange。对于这两个属性,反之亦然。

public int Width
{
get
{
return _width;
}

set
{
_width = value;
_height = YOUR CALCULATED VALUE
**All other bits you want to do here**

OnPropertyChanged("Width");
OnPropertyChanged("Height");
}
}

和高度属性类似

关于c# - 在 Viewmodel 属性中防止 StackOverFlow 或递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48791972/

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