在 wpf 中创建像 Powerpoint 缩略图一样的缩略图预览
Creating Thumbnail Preview like Powerpoint thumnails in wpf
我有一个带有两个面板的 wpf 应用程序,类似于 powerpoint 应用程序:
- 左窗格显示列表框中所有面板的列表
- 显示所选面板的右窗格
在列表框中,我想将面板显示为缩略图,并将缩略图更新为当新控件添加到右窗格中的面板时的缩略图。
就像 powerpoint 应用程序缩略图行为一样。
通过使用RenderTargetBitmap
和PngBitmapEncoder
我们可以捕获window的区域。
并使用 PngBitmapEncoder
帧 属性 将其分配给图像源。
让我们从 Xaml
开始
我把window分成左右两半。在 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>
只要你点击左边的面板项,相应的控件就会和数据一起显示在右边的面板上。
为了跟踪 ListBox
中的项目,我使用了 Dictionary
和 ItemIndex
并且它对应的项目索引使用了控件。
Window的代码隐藏
/// <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
然后从 _dictionaryControls[=62 获取 TextBox
控制=] 基于 ListBox 的 SelectedIndex 并通过获取 StackPanel
.
的当前快照将其放置在 StackPanel
中
出于演示目的,我只对 TextBox
控件进行了此操作,但您可以对任何其他控件进行一些微调。
UpdateThumbNail 创建了一个方法,负责根据 ListBoxItem 更新列表框中的图像。
dispatcherTimer_Tick : - 事件负责每秒调用 UpdateThumbNail() 方法。
我有一个带有两个面板的 wpf 应用程序,类似于 powerpoint 应用程序:
- 左窗格显示列表框中所有面板的列表
- 显示所选面板的右窗格
在列表框中,我想将面板显示为缩略图,并将缩略图更新为当新控件添加到右窗格中的面板时的缩略图。
就像 powerpoint 应用程序缩略图行为一样。
通过使用RenderTargetBitmap
和PngBitmapEncoder
我们可以捕获window的区域。
并使用 PngBitmapEncoder
帧 属性 将其分配给图像源。
让我们从 Xaml
开始我把window分成左右两半。在 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>
只要你点击左边的面板项,相应的控件就会和数据一起显示在右边的面板上。
为了跟踪 ListBox
中的项目,我使用了 Dictionary
和 ItemIndex
并且它对应的项目索引使用了控件。
Window的代码隐藏
/// <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
然后从 _dictionaryControls[=62 获取 TextBox
控制=] 基于 ListBox 的 SelectedIndex 并通过获取 StackPanel
.
StackPanel
中
出于演示目的,我只对 TextBox
控件进行了此操作,但您可以对任何其他控件进行一些微调。
UpdateThumbNail 创建了一个方法,负责根据 ListBoxItem 更新列表框中的图像。
dispatcherTimer_Tick : - 事件负责每秒调用 UpdateThumbNail() 方法。