0
votes

I previously used Caliburn.Micro for my projects before universal windows application. Now I'm porting my apps to universal windows and decided to use Prism Library. Because there are lots of uwp sample for that. But I'm too beginner and don't know how to convert my old viewmodels.

I'm using webview to show some generated html. In caliburn I can find webview in viewmodel using OnViewLoaded event;

    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;  
    }

But I didn't find any event can provide this. In prism there are only OnNavigatedTo and OnNavigatingFrom events.

Do prism have workaround for that?

1
You should not really use elements from the View in your ViewModel .. I use Caliburn any I solve this scenario by sending a message with the HTML content from the ViewModel to the ViewIgor Kulman
Igor is right. Using View types inside your ViewModel breaks the MVVM pattern and tightly couples your ViewModels with your View, making it hard to test and reuse. There are a few ways you can attempt, like create your own user control (code-behind allowed here) and expose dependency properties for viewmodel binding. Another possibility may be to use Blend interactivity trigger and actions to update an dependency property (which may bind an ICommand)Tseng

1 Answers

0
votes

Sorry about late reply,

I aggree with Igor and Tseng that will break MVVM pattern. But I'm trying to do something complex. Maybe there is a way of doing with it MVVM but I don't want to lose too much time on this.

What I found solution for the problem is as following. I wrote a 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;
    }
}

In my viewmodel, using following code finds WebView control. I'm using SplitView control thats why I'm using FindVisualChildInsideFrame method.

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

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