简体   繁体   中英

How to Convert XAML File (View) into DependencyObject?

I am working on a project where i have to deal with navigation based on Frame in MVVM pattern thus to get to the element Name x:Name of type Frame we have to convert MainWindow into DependencyObject like this..

 private static FrameworkElement GetDescendantFromName(DependencyObject parent, string name)
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);

            if (count < 1)
            {
                return null;
            }

            for (var i = 0; i < count; i++)
            {
                var frameworkElement = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
                if (frameworkElement != null)
                {
                    if (frameworkElement.Name == name)
                    {
                        return frameworkElement;
                    }

                    frameworkElement = GetDescendantFromName(frameworkElement, name);
                    if (frameworkElement != null)
                    {
                        return frameworkElement;
                    }
                }
            }
            return null;
        }

In Navigation Service Class i use...

var frame = GetDescendantFromName(Application.Current.MainWindow, "FrameName") as Frame;
frame.source = new Uri("Views/StudentView.Xaml");

This technique is limited to only MainWindow. When i pass new instence of EmployeeDetailView.Xaml as a depenecy Object, The Xaml File is not loaded and GetChildrenCount() returns 0.

var frame = GetDescendantFromName(EmployeeDetaiView.Xaml, "FrameName") as Frame;

here frame has null value. how could i make it work with currently rendered EmployeeDetailView to get the Frame element?

Use Application.LoadComponent Method (Uri)

Page p = (Page) Application.LoadComponent(new Uri("Views/EmployeeDetaiView.Xaml.xaml", UriKind.Relative));

var ctrl = GetDescendantFromName(p, "SomeControl");

Here, EmployeeDetaiView.Xaml lies in Views folder.

EDIT #1 after user comments

However, as pointed by OP in his comment that VisualTreeHelper.GetChildrenCount() is returning 0. This happens because p is not part of VisualTree , once it is part of VisualTree it will work correctly.

    Page p;
    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        p = (Page) Application.LoadComponent(new Uri("Views/EmployeeDetaiView.Xaml.xaml", UriKind.Relative));
        Frm.Content = p;

        // This will print 0
        int i = VisualTreeHelper.GetChildrenCount(p);
        System.Diagnostics.Debug.WriteLine("Children count = " + i);
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        // Now it will correctly print 1, as 'p' is now part of VisualTree
        int i = VisualTreeHelper.GetChildrenCount(p);
        System.Diagnostics.Debug.WriteLine("Children count = " + i);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM