WPF: добавить страницу с функциональностью в окно во время выполнения как XAML - PullRequest
3 голосов
/ 12 августа 2009

Я создал приложение WPF, в котором я динамически собираю элементы XAML с использованием кода c #, а затем добавляю их в корневую сетку «контейнера».

Что я пытаюсь сделать, так это воспользоваться возможностями Blend и создать несколько страниц XAML, которые имеют собственный набор кода для логики, раскадровки и т. Д.

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

Это то, что я делал раньше. В моем корневом окне я создаю новый MyModule и добавляю его в мой contentRoot.

 myModule = new MyModule();
 contentRoot.Children.Add(myModule );

(Подход, который работает) Класс MyModule расширяет Canvas и состоит из файла .XAML и кода .CS позади файла. XAML - это просто корневой холст, а в .CS есть вся логика для создания элементов и добавления их в корневой холст.

Когда я использую тот же подход, когда MyModule теперь расширяет страницу, ничего не появляется. В XAML теперь много контента, включая Canvas.Resources Canvas.Triggers и множество других элементов.

Как я могу загрузить предварительно созданный контент XAML из класса, включая код, лежащий в основе логики, во время выполнения?

Ответы [ 3 ]

4 голосов
/ 29 сентября 2009

Page и Canvas - два разных вида компонентов в XAML.

Страница - это элемент каркаса, а Canvas - это контейнер, в котором может быть несколько элементов управления с абсолютными координатами x, y. В противном случае у страницы есть только одно свойство «Контент», которое вы можете рассматривать как расширенный элемент управления контентом.

В Blend должны быть созданы методы, связанные с Canvas, которые будут похожи на "Canvas.SetLeft" и т. Д., Но они, безусловно, не будут работать в Page.

Ваш класс Page должен иметь одно содержимое типа «Canvas», и вы должны добавить все элементы управления внутри «Canvas» на внутренней странице, которые вам помогут.

Это текст из MSDN,

Страница может иметь только один дочерний элемент. Все остальные элементы на странице должны быть потомками этого элемента. Как правило, содержимое страницы содержит элемент макета, например Grid, StackPanel и DockPanel, который содержит содержимое страницы.

В вашем случае, Страница должна содержать один элемент "Холст" и добавлять элементы.

Или почему бы вам не попробовать этот вариант, пусть ваш MyModule будет таким же, как он есть, и вы создадите новую страницу под названием MyModulePage, и она должна выглядеть следующим образом.

<MyModulePage>
    <MyModule/> <!-- that is your canvas generated in blend -->
</MyModulePage>
3 голосов
/ 28 сентября 2009

Я нахожу этот вопрос немного неясным, но вот кое-что, что сработало для меня.

Определить MyModule как:

<Page x:Class="WpfApplication3.MyModule"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
</Page>


public partial class MyModule : Page
{
    public MyModule()
    {
        InitializeComponent();
        this.Content = new TextBlock(new Run("WOW!"));
    }
}

Создал отдельный файл с именем MyModuleStandalone.xaml:

<local:MyModule xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:local="clr-namespace:WpfApplication3;assembly=WpfApplication3"                
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</local:MyModule>

Код ниже работает. Когда я показываю c, он отображает текстовый блок с текстом «WOW!».

FileStream xamlFile = new FileStream("MyModuleStandalone.xaml", FileMode.Open, FileAccess.Read);
MyModule c= (MyModule)XamlReader.Load(xamlFile);
this.Content = c;

Локальная переменная c c является экземпляром MyModule, поэтому доступен весь код этого класса. Это то, что вы ищете?

Вы не можете использовать атрибут x: Class в вашем автономном файле XAML, поскольку это означает, что XAML является частичным классом, а остальная часть класса объявлена ​​где-то еще. XamlReader просто не будет его поддерживать.

Помните, что при чтении в файле XAML вы читаете в сериализованном объекте . Невозможно динамически внедрить код в произвольный автономный файл xaml.

0 голосов
/ 12 августа 2009
  FileStream xamlFile = new FileStream("Resources/News/NewsModuleCanvas.xaml", FileMode.Open, FileAccess.Read);
  Canvas newsCanvas = (Canvas)XamlReader.Load(xamlFile);
  contentRoot.Children.Add(newsCanvas);

Использовал это для загрузки XAML, однако это по-прежнему не дает мне возможности также добавлять код за логикой.

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