Как сделать проверенный CheckBox (тема Aero) на RenderTargetBitmap? - PullRequest
4 голосов
/ 08 октября 2010

Мой флажок отображается без флажка.Если я использую только один флажок (экземпляр объекта) для рендеринга, тогда я могу получить флажок, чтобы показать, но я не могу использовать это решение.Мне нужно быть в состоянии сделать это с помощью локального флажка.Этот флажок имеет тему Aero, примененную к нему через "/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", и это также должно быть для меня.Другие темы встроены в такие темы, как Royal и Luna, с галочкой.

XAML

<Canvas Name="canvas">
  <Button Click="Button_Click" Canvas.Left="440" Canvas.Top="277">
      Do Paint
  </Button>
  <Image Name="image"/>
</Canvas> 

C #

private void Button_Click(object sender, RoutedEventArgs e) {
  var checkBox = new CheckBox { Width = 100, Height = 30, IsChecked = true, };
  var rectangle = new Rect(0, 0, checkBox.Width, checkBox.Height);

  //need this
  var visualBrush = new VisualBrush(checkBox);
  checkBox.Arrange(rectangle);

  var renderTargetBitmap = new RenderTargetBitmap((int)rectangle.Width, (int)rectangle.Height, 96, 96, PixelFormats.Default);
  renderTargetBitmap.Render(checkBox);
  renderTargetBitmap.Freeze();

  image.Source = renderTargetBitmap;
}

1 Ответ

4 голосов
/ 08 октября 2010

Я использовал Reflector для просмотра содержимого сборки PresentationFramework.Aero и узнал, что здесь происходит. У меня есть решение, но вам, вероятно, оно не понравится ...

В теме Aero флажки отображаются с элементом управления BulletChrome. Этот элемент управления использует анимацию при переключении из одного состояния в другое, поэтому при рендеринге флажка анимация от непроверенного к проверенному не завершена, а отметка не отображается. Так что вам нужно дождаться завершения анимации ...

Простое помещение Thread.Sleep перед рендерингом не будет работать, потому что, пока поток диспетчера находится в спящем режиме, анимация будет остановлена. Так что вам нужно начать новый поток, где вы ждете перед рендерингом флажок:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var checkBox = new CheckBox { Width = 100, Height = 30, IsChecked = true, };
        var rectangle = new Rect(0, 0, checkBox.Width, checkBox.Height);

        //need this
        var visualBrush = new VisualBrush(checkBox);
        checkBox.Arrange(rectangle);

        new Thread(() =>
            {
                Thread.Sleep(300); // the animation lasts 300ms
                Dispatcher.Invoke(() =>
                                {
                                    var renderTargetBitmap =
                                        new RenderTargetBitmap((int)rectangle.Width,
                                                            (int)rectangle.Height, 96, 96,
                                                            PixelFormats.Default);
                                    renderTargetBitmap.Render(checkBox);
                                    renderTargetBitmap.Freeze();

                                    image.Source = renderTargetBitmap;
                                });
            }).Start();
    }

(в этом коде используется метод расширения DispatcherExtensions.Invoke, поэтому вам нужно обратиться к сборке System.Windows.Presentation и импортировать пространство имен System.Windows.Threading)

Обратите внимание, что анимация не происходит, если SystemParameters.ClientAreaAnimation имеет значение false. Но так как это свойство доступно только для чтения, оно вам не очень поможет ...

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