【问题标题】:How to find framework element inside viewmodel using Prism如何使用 Prism 在视图模型中查找框架元素
【发布时间】:2016-01-05 08:43:18
【问题描述】:

在通用 Windows 应用程序之前,我曾在我的项目中使用过 Caliburn.Micro。现在我将我的应用程序移植到通用窗口并决定使用 Prism Library。因为有很多 uwp 样本。但是我太初学者了,不知道如何转换我的旧视图模型。

我正在使用 webview 来显示一些生成的 html。在 caliburn 中,我可以使用 OnViewLoaded 事件在 viewmodel 中找到 webview;

    protected override void OnViewLoaded(object view)
    {
        base.OnViewLoaded(view);

        var frameworkElement = view as FrameworkElement;
        if (frameworkElement == null)
            throw new ArgumentException();

        var browser = frameworkElement.FindName("browser") as WebView;
        if (browser == null)
            throw new ArgumentException();

        _webBrowser = browser;  
    }

但是我没有发现任何事件可以提供这个。在 prism 中只有 OnNavigatedToOnNavigatingFrom 事件。

prism 有解决方法吗?

【问题讨论】:

  • 您不应该在 ViewModel 中真正使用 View 中的元素。我使用 Caliburn 任何我通过将带有 HTML 内容的消息从 ViewModel 发送到 View 来解决这种情况
  • 伊戈尔是对的。在 ViewModel 中使用 View 类型会破坏 MVVM 模式并将 ViewModel 与 View 紧密耦合,从而难以测试和重用。您可以尝试几种方法,例如创建自己的用户控件(此处允许使用代码隐藏)并公开视图模型绑定的依赖项属性。另一种可能性可能是使用 Blend 交互触发器和操作来更新依赖属性(可能绑定 ICommand)

标签: mvvm prism uwp


【解决方案1】:

抱歉回复晚了,

我同意 Igor 和 Tseng 的观点,这将打破 MVVM 模式。但我正在尝试做一些复杂的事情。也许有一种方法可以使用 MVVM,但我不想在这方面浪费太多时间。

我找到的问题解决方案如下。我写了VisualHelper

public class VisualHelper
{
    public static T FindVisualChildInsideFrame<T>(DependencyObject depObj) where T : DependencyObject
    {
        var frame = FindVisualChild<Frame>(depObj);

        if (frame != null && frame.Content is Page)
            return FindVisualChild<T>(frame.Content as Page);

        return null;
    }

    public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    return (T)child;
                }

                T childItem = FindVisualChild<T>(child);
                if (childItem != null)
                    return childItem;
            }
        }
        return null;
    }
}

在我的视图模型中,使用以下代码找到WebView 控件。我使用SplitView 控制这就是我使用FindVisualChildInsideFrame 方法的原因。

public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary<string, object> viewModelState)
{
    base.OnNavigatedTo(e, viewModelState);

    var browser = VisualHelper.FindVisualChildInsideFrame<WebView>(Window.Current.Content);
}

【讨论】:

    猜你喜欢
    • 2011-03-12
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多