MainWindow
런타임에 로드하는 사용자 정의 컨트롤이 있습니다. 에서 포함 창에 대한 핸들을 얻을 수 없습니다 UserControl
.
시도 this.Parent
했지만 항상 null입니다. 누구나 WPF의 사용자 정의 컨트롤에서 포함 창에 대한 핸들을 얻는 방법을 알고 있습니까?
컨트롤이로드되는 방법은 다음과 같습니다.
private void XMLLogViewer_MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem application = sender as MenuItem;
string parameter = application.CommandParameter as string;
string controlName = parameter;
if (uxPanel.Children.Count == 0)
{
System.Runtime.Remoting.ObjectHandle instance = Activator.CreateInstance(Assembly.GetExecutingAssembly().FullName, controlName);
UserControl control = instance.Unwrap() as UserControl;
this.LoadControl(control);
}
}
private void LoadControl(UserControl control)
{
if (uxPanel.Children.Count > 0)
{
foreach (UIElement ctrl in uxPanel.Children)
{
if (ctrl.GetType() != control.GetType())
{
this.SetControl(control);
}
}
}
else
{
this.SetControl(control);
}
}
private void SetControl(UserControl control)
{
control.Width = uxPanel.Width;
control.Height = uxPanel.Height;
uxPanel.Children.Add(control);
}
답변
다음을 사용해보십시오.
Window parentWindow = Window.GetWindow(userControlReference);
이 GetWindow
메서드는 VisualTree를 안내하고 컨트롤을 호스팅하는 창을 찾습니다.
GetWindow
메서드가 반환 되지 않도록하려면 컨트롤이로드 된 후 (창 생성자가 아닌)이 코드를 실행해야합니다 null
. 예를 들어 이벤트를 연결하십시오.
this.Loaded += new RoutedEventHandler(UserControl_Loaded);
답변
내 경험을 추가하겠습니다. Loaded 이벤트를 사용하면 작업을 수행 할 수 있지만 OnInitialized 메서드를 재정의하는 것이 더 적합 할 수 있습니다. 창을 처음 표시 한 후로드가 발생합니다. OnInitialized를 사용하면 렌더링 전에 창에 컨트롤을 추가하는 등의 변경 작업을 수행 할 수 있습니다.
답변
VisualTreeHelper.GetParent를 사용하거나 벨로우 재귀 함수를 사용하여 부모 창을 찾으십시오.
public static Window FindParentWindow(DependencyObject child)
{
DependencyObject parent= VisualTreeHelper.GetParent(child);
//CHeck if this is the end of the tree
if (parent == null) return null;
Window parentWindow = parent as Window;
if (parentWindow != null)
{
return parentWindow;
}
else
{
//use recursion until it reaches a Window
return FindParentWindow(parent);
}
}
답변
Loaded 이벤트 처리기에서 Window.GetWindow (this) 메서드를 사용해야했습니다. 즉, Ian Oakes의 대답과 Alex의 대답을 함께 사용하여 사용자 정의 컨트롤의 부모를 얻었습니다.
public MainView()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainView_Loaded);
}
void MainView_Loaded(object sender, RoutedEventArgs e)
{
Window parentWindow = Window.GetWindow(this);
...
}
답변
이 방법은 저에게 효과적이지만 귀하의 질문만큼 구체적이지 않습니다.
App.Current.MainWindow
답변
이 질문을 찾았는데 VisualTreeHelper가 작동하지 않거나 산발적으로 작동하지 않는 경우 알고리즘에 LogicalTreeHelper를 포함시켜야합니다.
여기 내가 사용하는 것이 있습니다 :
public static T TryFindParent<T>(DependencyObject current) where T : class
{
DependencyObject parent = VisualTreeHelper.GetParent(current);
if( parent == null )
parent = LogicalTreeHelper.GetParent(current);
if( parent == null )
return null;
if( parent is T )
return parent as T;
else
return TryFindParent<T>(parent);
}
답변
이건 어때요:
DependencyObject parent = ExVisualTreeHelper.FindVisualParent<UserControl>(this);
public static class ExVisualTreeHelper
{
/// <summary>
/// Finds the visual parent.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sender">The sender.</param>
/// <returns></returns>
public static T FindVisualParent<T>(DependencyObject sender) where T : DependencyObject
{
if (sender == null)
{
return (null);
}
else if (VisualTreeHelper.GetParent(sender) is T)
{
return (VisualTreeHelper.GetParent(sender) as T);
}
else
{
DependencyObject parent = VisualTreeHelper.GetParent(sender);
return (FindVisualParent<T>(parent));
}
}
}