Каков наилучший способ обмена данными между окном WPF и его пользовательскими элементами управления? - PullRequest
6 голосов
/ 07 января 2012

WPF иногда может приводить в бешенство.

У меня довольно простое приложение, которое состоит из одного главного окна, которое содержит элемент управления вкладками и несколько вкладок. Мне не понравилась идея иметь код для всех вкладок в одном файле, поэтому я использовал ответ из этого вопроса , чтобы разбить каждую вкладку на отдельный пользовательский элемент управления.

Внутри моего главного окна у меня есть экземпляр объекта, который содержит настройки приложения и некоторые другие данные приложения. Некоторые из моих вкладок требуют доступа к этим данным для привязки данных. Я не смог найти хороший способ сделать это.

Сначала я попытался получить доступ к родительскому окну в событии Loaded для элементов управления и получить ссылку на свойство в главном окне, которое отображает объект настроек, как показано в коде ниже. Этот вид работ, за исключением события Loaded, запускается каждый раз, когда вкладка получает фокус. Кроме того, это событие происходит в конце жизненного цикла элемента управления, поэтому я не могу привязать ни одно из свойств этого объекта в пользовательском элементе управления XAML.

private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
{
    this.ApplicationSettings = ((MainWindow)Window.GetWindow(this)).ApplicationSettings;
}

Затем я экспериментировал с передачей данных в конструктор пользовательских элементов управления, но в XAML этого не было.

Учитывая, что это настройки для всего приложения, я мог бы сделать синглтон класса ApplicationSettings и ссылаться на него везде, но я бы предпочел не делать этого для целей модульного тестирования.

Так, как можно сделать что-то подобное? Является ли мой подход в корне ошибочным? На мой взгляд, все эти элементы пользовательского интерфейса являются частью одного и того же окна и, следовательно, должны иметь возможность доступа к данным из главного окна, но объектная модель, по-видимому, не позволяет этого.

Ответы [ 3 ]

2 голосов
/ 07 января 2012

Вы можете поместить объект настроек в статическое свойство в классе-оболочке (SettingsHolder в этом примере и ссылаться на него по всему приложению через

в XAML:

{Binding SettingName, Source={x:Static local:SettingsHolder.Settings}}

с помощью local - это пространство имен, в котором находится ваш SettingsHolder класс.

в коде:

var x = SettingsHolder.Settings.SettingName;
SettingsHolder.Settings.SettingName = x;
1 голос
/ 07 января 2012

В объявлении вашего пользовательского элемента управления вы можете просто установить контекст данных для экземпляра объекта, который содержит все, что вам нужно привязать!

<someNamespace:EricsUserControl DataContext="{Binding InstanceOfBindingObject}"/>

Затем вы можете получить доступ к свойствам экземпляра этих объектов в пользовательском элементе управления, как обычно.

0 голосов
/ 08 января 2012

Я использую Frame в Tab и помещаю Page в Frame. (но я думаю, что то же самое можно применить с пользовательским элементом управления). Конструктор срабатывает только при создании страницы, и вы можете контролировать, когда страница создается, и вы можете передавать информацию в конструктор. Страница имеет больше событий жизненного цикла, чтобы связать их. Я также использую событие Loaded для создания пользовательского интерфейса (оно срабатывает только один раз). Если вы связываете страницу в XAML, она запускается при запуске приложения, и вы не можете передавать информацию. Это создает страницу и показывает ее в диалоговом окне, но эта страница может быть связана с фреймом.

        NavigationWindow winSearchXML;
        using (new WaitCursor())
        {
            winSearchXML = new NavigationWindow();
            winSearchXML.Content = new PageSearchResultsXML(GabeLib.GetSearchXML(GabeLib.enumXMLtype.Flat));
        }
        winSearchXML.ShowDialog();

Мне нужно быть честным, что иногда я получаю жизненный цикл на странице, которую я просто не понимаю. Так что возьми это с крошкой соли. Но дело в том, что у вас есть конструктор и загруженные события, которые могут дать вам то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...