Создание предварительного просмотра миниатюр как PowerPoint thumnails в wpf - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть приложение wpf с двумя панелями, похожее на приложение powerpoint:

  • левая панель, которая показывает список всех панелей в списке
  • правая панель, которая показывает выбранную панель

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

Точно так же, как поведение миниатюр приложения Powerpoint.

1 Ответ

0 голосов
/ 10 декабря 2018

Используя RenderTargetBitmap и PngBitmapEncoder, мы можем захватить область окна.и с помощью свойства кадра PngBitmapEncoder, назначенного для Image Source.

Давайте начнем с Xaml

Я разделил окно на две половины и левую и правую панели.То же самое в PowerPoint с меньшим стилем.Для демонстрации я реализовал добавление TextBox на правой панели, а предварительный просмотр будет отображаться на миниатюре левой панели.

    <Grid Background="Aqua" x:Name="gridg">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ListBox   HorizontalAlignment="Left" Height="372" Margin="10,38,0,0" VerticalAlignment="Top" Width="306" Grid.Column="0" x:Name="Listtems" SelectionChanged="Listtems_SelectionChanged" />

    <Button Content="+ TextBox" HorizontalAlignment="Left" Margin="142,10,0,0" VerticalAlignment="Top" Width="174" Click="Button_Click" Grid.Column="0"/>
    <StackPanel x:Name="stackPanel" Background="Wheat" Grid.ColumnSpan="2" Margin="321,0,0,0"  />
    </Grid>

enter image description here

Как только вы нажмете на элемент левой панели, соответствующий элемент управления будет отображаться на правой панели с данными.

Чтобы отследить элементы в ListBox, я использовал Dictionary с ItemIndex и для соответствующего индекса использованного элемента управления.

Код окна позади

/// <summary>
/// Interaction logic for Window6.xaml
/// </summary>
public partial class Window6 : Window
{
    Dictionary<int, Control> _dictionaryControls = new Dictionary<int, Control>();
    DispatcherTimer dispatcherTimer = new DispatcherTimer();
    public Window6()
    {
        InitializeComponent();
        dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Start();
    }


    private void BmpImage()
    {
        RenderTargetBitmap renderTargetBitmap =
        new RenderTargetBitmap(800, 450, 96, 96, PixelFormats.Pbgra32);
        renderTargetBitmap.Render(stackPanel);
        PngBitmapEncoder pngImage = new PngBitmapEncoder();
        pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

        Image img = new Image();
        img.Source = pngImage.Frames[0];
        img.Height = 148;
        img.Width = 222;
        Listtems.Items.Add(img);
        Listtems.SelectedIndex = Listtems.Items.Count - 1;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        stackPanel.Children.Clear();
        int item = Listtems.Items.Count;
        TextBox txtControl = new TextBox();
        txtControl.FontSize = 100;
        txtControl.Height = 122;
        txtControl.TextWrapping = TextWrapping.Wrap;
        _dictionaryControls.Add(item, txtControl);
        stackPanel.Children.Add(txtControl);
        stackPanel.UpdateLayout();
        BmpImage();
    }

    private void Listtems_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        UpdateThumbNail();
    }

    private void UpdateThumbNail()
    {
        int indexbackup = -1;
        Listtems.SelectionChanged -= Listtems_SelectionChanged;
        Control control;

        _dictionaryControls.TryGetValue(Listtems.SelectedIndex, out control);
        if (control == null)
        {
            Listtems.SelectionChanged += Listtems_SelectionChanged;
            return;
        }

        indexbackup = Listtems.SelectedIndex;

        stackPanel.Children.Clear();
        stackPanel.Children.Add(control);
        stackPanel.UpdateLayout();

        RenderTargetBitmap renderTargetBitmap =
            new RenderTargetBitmap(800, 450, 96, 96, PixelFormats.Pbgra32);
        renderTargetBitmap.Render(stackPanel);
        PngBitmapEncoder pngImage = new PngBitmapEncoder();
        pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

        Image img = new Image();
        img.Source = pngImage.Frames[0];
        img.Height = 148;
        img.Width = 222;

        Listtems.Items.Insert(Listtems.SelectedIndex, img);
        Listtems.Items.RemoveAt(Listtems.SelectedIndex);

        Listtems.SelectedIndex = indexbackup;
        Listtems.SelectionChanged += Listtems_SelectionChanged;

    }


    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        UpdateThumbNail();
    }
}

BmpImage (): - Я использовал для захвата или, другими словами, экран печати элемента управления StackPanel.

Событие Button_Click : - Используется для создания нового элемента в ListBox, добавляя изображение с текущим экраном печати элемента управления TextBox в StackPanel.Он также добавляет элемент управления в переменную _dictionaryControls .

Событие Listtems_SelectionChanged : - очищает StackPanel и затем получает элемент управления TextBox из _dictionaryControls на основе SelectedIndex ListBox и поместите его в StackPanel, сделав текущий снимок StackPanel.

Для демонстрационных целей, я сделал это только для TextBox Control, но вы можете сделатьэто для любого другого контроля с небольшой настройкой.

UpdateThumbNail создал метод, отвечающий за обновление изображения в Listbox, на основе ListBoxItem.

dispatcherTimer_Tick : - Событие отвечает за вызов UpdateThumbNail() Метод за каждую секунду.

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