【问题标题】:Binding a ScrollViewer from ViewModel to View将 ScrollViewer 从 ViewModel 绑定到 View
【发布时间】:2014-01-29 16:06:40
【问题描述】:

我在我的 ViewModel 中构建一个 scrollViewer 及其元素,它被构建到一个属性 FrameworkElement PageElement 中,我每次发生某些事件时都重建 pageElement,我想将 PageElement 绑定到视图中的一个真正的 scrollViewer这样每当我更改 pageElement 时,它就会在它的视图中绘制自己。

【问题讨论】:

  • 在您的 VM 中构建 UI 元素是不是 MVVM。您应该注意 UI 中的 UI 问题以及 VM 中的程序逻辑。
  • 你到底想达到什么目的?
  • 我正在尝试根据很多逻辑条件构建 UI 元素,这就是为什么我必须在 VM 中完成它。问题是如何将构建的 FrameWorkElement 发送到视图。
  • 你没有“必须”在虚拟机中做任何事情。你总是可以从后面的代码中获取虚拟机 var vm = myControl.DataContext as MyVMType ... Task.Factory.StartNew(async() =>{ //你的长期运行逻辑 });
  • @Will,说“不是 MVVM”很微妙。我认为它可以是绑定或不绑定 UI 元素的 MVVM。话虽如此,我将继续这样做会使 MVVM 的许多好处无效。围绕如此灵活的模式阅读最后通牒只是一件奇怪的事情。

标签: xaml mvvm windows-8 binding winrt-xaml


【解决方案1】:

让我给你一个小小的扶手椅建议。我不知道你项目的细节,但你问题中的细节让我得出了一些结论。

首先,让您的视图模型创建 UI 元素并没有错。但这真的很不寻常。听起来您可能缺少数据模板或数据模板选择器的概念。

  1. 使用数据模板可以让您拥有丰富的数据表示,这些数据是在重复器或单个内容控件中生成和呈现单个记录时构建的。

  2. 使用数据模板选择器可以让您拥有各种不同的数据表示,使用代码隐藏逻辑将根据数据或其他标准在这些表示之间切换。

参考模板:http://blog.jerrynixon.com/2012/08/windows-8-beauty-tip-using.html

其次,由于引发事件而重新生成 UI,这听起来像是解决性能问题的捷径。

  1. 每次您手动创建元素并将它们添加到可视化树时,您的应用都会面临在重新渲染布局时出现绑定延迟的风险。在 ARM 上运行你的应用程序,我打赌你可能已经看到了。再说一次,简单的 UI 可能不会受到这个一般经验法则的影响。

  2. 因为我不知道该事件,所以我不能假设它经常发生。但是,如果它经常发生,那么即使是简单的 UI 也会受到影响。

现在回答您的问题

Sherif,scrollviewer 上没有可以设置水平或垂直偏移的可写属性。设置scrollviewer 的偏移量的唯一方法是调用changeview()

var s = new ScrollViewer();
s.ChangeView(0, 100, 0);

你不能绑定到一个方法,所以绑定到这样的东西是不可行的,没有一些代码隐藏来读取所需的偏移量并直接调用该方法。

类似这样的:

public sealed partial class MainPage : Page
{
    MyViewModel _Vm = new MyViewModel();
    ScrollViewer _S = new ScrollViewer();
    public MainPage()
    {
        this.InitializeComponent();
        this._Vm.PropertyChanged += (s, e) =>
        {
            if (e.PropertyName.Equals("Offset"))
                _S.ChangeView(0, _Vm.Offset, 0);
        };
    }
}

public class MyViewModel : INotifyPropertyChanged
{
    private int _Offset;
    public int Offset
    {
        get { return _Offset; }
        set
        {
            _Offset = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Offset"));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

但是让我提醒你。偏移量需要基于某些东西。这些变量可能会根据窗口大小、字体大小、变换缩放以及许多其他因素而改变。上面的代码大部分时间都可以工作,但在其他设备上可能会经常失败。

那么,该怎么办?我的建议是您在代码隐藏中对此进行编码,监控您认为需要滚动的任何场景,然后简单地以编程方式从 bode-behind 滚动它。但请注意,以编程方式滚动滚动查看器可能会使您的 UI 让用户感到困惑。

您了解您的应用。你必须做出选择。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多