Попытайтесь использовать следующее:
Window parentWindow = Window.GetWindow(userControlReference);
GetWindow
метод обойдет VisualTree для Вас и определит местоположение окна, которое размещает Ваше управление.
необходимо выполнить этот код после того, как управление загрузилось (а не в конструкторе Окна), чтобы препятствовать тому GetWindow
метод возвращаться null
. Например, обеспечьте электричеством событие:
this.Loaded += new RoutedEventHandler(UserControl_Loaded);
Я нашел, что родитель UserControl является всегда пустым в конструкторе, но в любом случае обработчики родитель установлены правильно. Я предполагаю, что это должно иметь некоторое отношение к способу, которым загружается дерево управления. Таким образом для обхождения этого можно просто получить родителя в событии Loaded средств управления.
Для контроля в качестве примера этот вопрос Пользователь WPF Control' s DataContext Пустой
Я должен был использовать Окно. GetWindow (этот) метод в Загруженном обработчике событий. Другими словами, я использовал ответ обоих Ian Oakes в сочетании с ответом Alex для получения родителя пользовательского элемента управления.
public MainView()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainView_Loaded);
}
void MainView_Loaded(object sender, RoutedEventArgs e)
{
Window parentWindow = Window.GetWindow(this);
...
}
Попытайтесь использовать 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);
}
}
Вам нужно прочитать эту запись в блоге .
Также, вот очень минимальный скелет «канала» для связи между потоками:
public class Channel<T>
{
private readonly Queue<T> _queue = new Queue<T>();
public void Enqueue(T item)
{
lock (_queue)
{
_queue.Enqueue(item);
if (_queue.Count == 1)
Monitor.PulseAll(_queue);
}
}
public T Dequeue()
{
lock (_queue)
{
while (_queue.Count == 0)
Monitor.Wait(_queue);
return _queue.Dequeue();
}
}
}
-121--3772230- Перед использованием инверсии управления вы должны быть хорошо осведомлены о том, что он имеет свои достоинства и недостатки, и вы должны знать, почему вы используете его, если вы делаете это.
Достоинства:
Недостатки:
Лично я вижу сильные точки IoC и мне они очень нравятся, но я склонен избегать IoC, когда это возможно, потому что это превращает ваше программное обеспечение в набор классов, которые больше не составляют «реальная» программа, но только то, что нужно собрать вместе с помощью XML-конфигурации или метаданных аннотаций и будет падать (и разваливаться) без нее.
-121--1747331-Я добавлю свой опыт. Хотя использование события Loaded может выполнить задание, я думаю, что может быть более подходящим переопределить метод OnInitialized. Загрузка происходит после первого отображения окна. OnInitialized дает возможность вносить любые изменения, например добавлять элементы управления в окно перед его визуализацией.