Mam kontrolę użytkownika, którą ładuję do MainWindow
środowiska wykonawczego. Nie mogę uzyskać uchwytu na okno zawierające z UserControl
.
Próbowałem this.Parent
, ale zawsze jest nieważne. Czy ktoś wie, jak uzyskać uchwyt do zawierającego okno z kontrolki użytkownika w WPF?
Oto jak ładuje się kontrolkę:
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);
}
Dodam moje doświadczenie. Chociaż użycie zdarzenia Loaded może wykonać zadanie, myślę, że bardziej odpowiednie może być zastąpienie metody OnInitialized. Załadowane następuje po pierwszym wyświetleniu okna. OnInitialized daje szansę na dokonanie jakichkolwiek zmian, na przykład dodanie kontrolek do okna przed jego renderowaniem.
źródło
Window.GetWindow
nadal zwracanull
sięOnInitialized
. Wydaje się, że działa tylko w tymLoaded
wydarzeniu.Spróbuj użyć VisualTreeHelper.GetParent lub użyj poniższej funkcji rekurencyjnej, aby znaleźć okno nadrzędne.
źródło
Musiałem użyć metody Window.GetWindow (this) w module Loaded event handler. Innymi słowy, użyłem zarówno odpowiedzi Iana Oakesa w połączeniu z odpowiedzią Alexa, aby uzyskać rodzica kontroli użytkownika.
źródło
To podejście działało dla mnie, ale nie jest tak szczegółowe, jak twoje pytanie:
źródło
Jeśli znajdziesz to pytanie, a VisualTreeHelper nie działa dla ciebie lub działa sporadycznie, może być konieczne włączenie LogicalTreeHelper do algorytmu.
Oto czego używam:
źródło
LogicalTreeHelper.GetParent
w kodzie.Co powiesz na to:
źródło
Przekonałem się, że element nadrzędny UserControl jest zawsze pusty w konstruktorze, ale we wszystkich modułach obsługi zdarzeń rodzic jest ustawiony poprawnie. Myślę, że to musi mieć coś wspólnego ze sposobem ładowania drzewa kontrolnego. Aby obejść ten problem, po prostu umieść element nadrzędny w zdarzeniu formantu Loaded.
Na przykład pobranie tego pytania DataContext WPF User Control ma wartość Null
źródło
Inny sposób:
źródło
Działa dla mnie:
źródło
Nie działało to dla mnie, ponieważ poszło za daleko w górę drzewa i uzyskało absolutne okno główne dla całej aplikacji:
Jednak działało to, aby uzyskać bezpośrednie okno:
źródło
źródło
źródło
Pozłacane wydanie powyższego (potrzebuję ogólnej funkcji, która może wywnioskować
Window
w kontekścieMarkupExtension
: -MyWrapper.Owner()
poprawnie wnioskuje o oknie na podstawie:Window
przez chodzenie po drzewie wizualnym (jeśli jest używany w kontekście aUserControl
)Window
znaczników)źródło
Różne podejścia i różne strategie. W moim przypadku nie mogłem znaleźć okna mojego okna dialogowego za pomocą VisualTreeHelper lub metod rozszerzenia Telerik w celu znalezienia rodzica danego typu. Zamiast tego znalazłem mój widok okna dialogowego, który akceptuje niestandardowe wstrzykiwanie zawartości za pomocą Application.Current.Windows.
źródło
Window.GetWindow(userControl)
Powróci rzeczywistego okna tylko po zamknięciu okna został zainicjowany (InitializeComponent()
metoda zakończona).Oznacza to, że jeśli twoja kontrola użytkownika zostanie zainicjowana razem z jej oknem (na przykład umieścisz kontrolę użytkownika w pliku xaml okna), to w
OnInitialized
przypadku zdarzenia kontroli użytkownika nie otrzymasz okna (będzie puste), ponieważ w takim przypadkuOnInitialized
zdarzenie kontrolki użytkownika zostanie uruchomione przed zainicjowaniem okna.Oznacza to również, że jeśli twoja kontrola użytkownika jest zainicjowana po jej oknie, możesz uzyskać okno już w konstruktorze kontroli użytkownika.
źródło
Jeśli chcesz uzyskać konkretnego rodzica, nie tylko okno, konkretnego rodzica w strukturze drzewa, a także nie korzystasz z liczników pętli rekurencji lub twardego przerwania, możesz użyć następujących opcji:
Po prostu nie umieszczaj tego wywołania w konstruktorze (ponieważ
Parent
właściwość nie została jeszcze zainicjowana). Dodaj go w module obsługi zdarzenia ładowania lub w innych częściach aplikacji.źródło