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.