Как выполнить привязку данных вне и экземпляр System.Windows.Application - PullRequest
0 голосов
/ 23 марта 2011

Итак, вот senerio.

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

Я пытаюсь сделать это, имея шаблон.файл xaml и создание его экземпляра в проекте ClassLibrary.Таким образом, файл xaml создается вне области приложения WPF.

Я пытаюсь создать вид PivotCollection, как описано в этой ссылке

http://martimedia.blogspot.com/2010/07/creating-pivot-collection.html

Я закончил тем, что унаследовал от System.Windows.Application в своей библиотеке классов, чтобы это работало, но это далеко от идеала, так как это вызывает вопросы об используемом AppDomain.

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

Вот простое POCO, к которому я хотел бы привязаться.

public class DataObject {
   public DataObject(string value) {
      Property = value;
   }
   public string Property { get; set; }
}

Вот простой «Шаблон изображения», который я хотел быbind from.

<UserControl x:Class="XamlRenderingExample.Template"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   mc:Ignorable="d" 
   d:DesignHeight="300" d:DesignWidth="300">
  <Grid>
    <TextBlock Text="{Binding Property}"></TextBlock>
  </Grid>
</UserControl>

Вот простая библиотека классов для создания изображения из xaml

public class CreateBitmapImagesFromXamlTemplate {
  public CreateBitmapImagesFromXamlTemplate() {
     Template template = new Template();
     foreach (DataObject obj in GetDataObjects())
     {
        template.DataContext = obj;
        RenderXamlAsBitMap(template); 
     }
  }

  private void RenderXamlAsBitMap(Template template) {
     template.Arrange(new Rect(0, 0, 300, 300));
     RenderTargetBitmap bitmap = new RenderTargetBitmap((int)template.RenderSize.Width,
                       (int)template.RenderSize.Height,
                        96,
                        96, PixelFormats.Default);
     bitmap.Render(template);
     // Save away the bitmap to file.
  }

  private static List<DataObject> GetDataObjects() {
     return new List<DataObject>()
     {
        new DataObject("Hello"),
        new DataObject("Another string")
     };
  }
}

Проблема заключается в том, что без добавления Xaml в отображаемое окно в настройке приложения WPFdatacontext не будет выполнять желаемое связывание, и в результате textBlock не будет отображать данные из DataObject.

Как я понимаю, если бы мы были в приложении WPFшаблон и шаблон были добавлены в отображаемое окно, когда я установил dataContext шаблона, в диспетчере запрашивается задание для фактического выполнения обработки данных и извлечения значений из объекта DataObject в шаблон.

What Iя хочу выполнить эту процедуру вручную в моей библиотеке классов без необходимости создания экземпляра объекта System.Windows.Application.

У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 23 марта 2011

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

Я изменил вышеуказанный класс, чтобы поставить в очередь задания, которые теперь выполняют желаемую «привязку данных» для сохраненного изображения, используя следующий код:

public class CreateBitmapImagesFromXamlTemplate {
    Template template;
    RenderTargetBitmap bitmap;

public CreateBitmapImagesFromXamlTemplate() {
    template = new Template();

    foreach (DataObject obj in GetDataObjects()) {
        RenderXamlAsBitMap(template, obj); 
    }
}

private void RenderXamlAsBitMap(Template template, DataObject dataObject) {
    var renderFrame = new DispatcherFrame(true);
    QueueDataBinding(dataObject, renderFrame);
    QueueRenderBitmap(renderFrame);
    System.Windows.Threading.Dispatcher.PushFrame(renderFrame);  
    SaveRenderedBitmap(bitmap);
}

private static List<DataObject> GetDataObjects() {
    return new List<DataObject>() {
    new DataObject("Hello"),
        new DataObject("Another string")
  };
}

private void SaveRenderedBitmap(RenderTargetBitmap renderedBitmap) {
    var encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(renderedBitmap));
    using (FileStream fs = File.Open(@"C:\temp\imageTesting.jpg", 
        FileMode.OpenOrCreate)) {
            encoder.Save(fs);
        }
    }

    private void QueueDataBinding(DataObject dataObject, 
    DispatcherFrame renderFrame) {
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.DataBind, 
            (ThreadStart)delegate() {
            template.DataContext = dataObject;
            renderFrame.Continue = true;
  });
}

private void QueueRenderBitmap(DispatcherFrame renderFrame) {
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
        (ThreadStart)delegate() {
        RenderBitmap();
        renderFrame.Continue = false;
        });
    }

    private void RenderBitmap() {
        template.Arrange(new Rect(0, 0, 300, 300));
        bitmap = new RenderTargetBitmap((int)template.RenderSize.Width,
            (int)template.RenderSize.Height,
            96,
            96, PixelFormats.Default);
        bitmap.Render(template);
        SaveRenderedBitmap(bitmap);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...