c# - 如何从 View 模型访问不可绑定(bind)的 View 属性?

标签 c# wpf mvvm data-binding telerik

我正在使用 Telerik WPF RadGanttView控件显示一堆数据。由于数据可能是任意奇怪的 - 瞬时事件,或者最后几天,或者它们之间有一周 - 不可能设置 PixelLength (即比例因子)保证有用。我被要求用 slider 改变这个比例因子。不幸的是,仅使用 slider 更改比例因子存在可用性问题,我需要通过手动调整 View 的滚动位置来解决此问题。我不知道到底是怎么回事。

概述我正在修复的可用性问题: View 通过在数据集的整个“范围”上提供位于“偏移”处的“视口(viewport)”来工作。 (从 Telerik API 中提取的术语。这些似乎只是表示可 ScrollView 下的 Canvas 中的像素。)当比例因子从 100% 变为 200% 时(对应于减半 PixelLength ),什么发生的是范围的宽度加倍,但水平 offset保持原样。结果是,在放大之后,您很可能会看到与以前完全不同的数据,因为之前存在的事件已从右侧的视口(viewport)中“拉出”。

我打算解决这个问题的方法是:在放大之前获取偏移量/视口(viewport)/范围等,然后用新的偏移量/视口(viewport)/范围做一些我还没有弄清楚的数学运算。问题是:RadGanttView 的属性描述滚动的东西是不是 DependencyProperty s,我不能简单地将它们绑定(bind)到我的 ViewModel 上的属性。 . (事实上​​,它们甚至无法在 XAML 中访问,RadGanttView 明确地实现了 IScrollingInfo。)

所以,我的问题是:我该怎么做,在我的 ViewModel , 或任何其他对 ViewModel 作出 react 的地方的比例因子变化,访问相应View中的控件属性,那不能是数据绑定(bind)的?我尝试的每次搜索都告诉我从 View 模型访问 View “不是 MVVM”,但由于 Telerik 是第三方库,我无法真正重构它在他们方面的工作方式。

我的代码的填空大纲:

FooViewModel.cs

class FooViewModel 
{

    // A slider in the view pushes its value into this property
    double ScaleFactor 
    {
        get { /*...*/ }
        set
        {
            PixelLength = GetNewPixelLength(value);
            // ...
        }
    }

    // The RadGanttView pulls its scale from this property
    double PixelLength
    {
        get { ... }
        set
        {
            // How do I get these values?
            var oldOffset = ???;
            var oldExtent - ???;

            // Trigger the actual change in the view.
            PropertyChanged("PixelLength", ...);

            var newExtent = ???;
            ???.HorizontalOffset =  GetNewOffset(...);
        }
    }
}

FooView.xaml

<UserControl ... d:DataContext="{d:DesignInstance my:FooViewModel}">
    <telerik:RadGanttView x:Name="Gantt">
        <!-- ... -->
    </telerik:RadGanttView>
</UserControl>

我调查过的事情:
  • 制作一堆DependencyProperty FooView 中的包装器仅访问 RadGanttView 中的相应属性的代码隐藏.这似乎都是对系统的可怕滥用 - 即,拥有不受 DependencyObject 支持的依赖属性似乎没有意义。 .而且它根本不起作用 - 在 WPF 中, View 似乎将数据“推送”到 View 模型中,我仍然无法实际获取当前值,因为包装器属性的值永远不会得到更新。
  • 呃,Command s,也许?我是 WPF 的新手,我根本不知道它们是如何工作的,只是一个模糊的印象,它们可能是 View 模型与 View 对话的松散耦合方式。
  • 附加属性?自定义绑定(bind)?远远高于我的工资等级,如果他们帮助我自己不知道如何。似乎他们可以完成将控件绑定(bind)到 View 模型属性的“肮脏”解决方案。由于该属性的类型为 IScrollingInfo ,而不是整个 View ,我可以忍受。
  • 最佳答案

    附加行为可能会解决您的问题。它们基本上是带有回调的附加属性。

    看看我的回答 here .只是代替 KeyDown事件,您注册到Changed事件(或您的控件实际调用它的任何内容),然后将从 Changed 事件中获得的值分配给您的附加属性,并且您在不可绑定(bind)属性上有两种方式绑定(bind)

    关于c# - 如何从 View 模型访问不可绑定(bind)的 View 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29158625/

    相关文章:

    c# - 如何从 WPF 中的堆栈面板中删除最后一个子项?

    wpf - 构建 WPF 客户端应用程序时本地数据库与基于服务的数据库

    c# - Xamarin.Forms MVVM Light IDialogService ShowMessage 抛出 native 异常

    swift - 无法将类型 'Int' 的返回表达式转换为返回类型“Property<Int>”

    wpf - 错误: 'Cannot create unknown type ' {clr-namespace:NameSpace.Properties}“设置”。

    c# - MVVM - 如何使格式化属性保持最新?

    c# - 如何在网格中添加多个自定义形状的按钮?

    c# - 如何判断一个C#控件是否正在被卸载?

    c# - Visual Studio 中的 MSBuild - 在将文件包含为内容之前移动文件 (C#)

    wpf - 如何为 WPF 工具包图表赋予样式