<ItemsControl ItemsSource="{Binding ElpsCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Width="{Binding Width}"
Height="{Binding Height}"
Fill="{Binding ElpColor}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ContextMenu>
<ContextMenu>
<MenuItem Header="ReGenerate Ellipses"
Command="{Binding ReGenerateEllipsesCommand}"/>
<MenuItem Header="Save As Jpg"
Command="{Binding SaveAsJpgCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContextMenu}},
Path=PlacementTarget}"/>
</ContextMenu>
</ItemsControl.ContextMenu>
</ItemsControl>
private void SaveFrameworkElementAsPicture(FrameworkElement fe,string jpgFile,int dpi=96)
{
Size size = new Size(fe.ActualWidth, fe.ActualHeight);
RenderTargetBitmap rtb=new RenderTargetBitmap(
(int)(size.Width * dpiFactor),
(int)(size.Height * dpiFactor),
dpi*dpiFactor,
dpi*dpiFactor,
PixelFormats.Pbgra32);
DrawingVisual drawingVisual=new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
VisualBrush visualBrush = new VisualBrush(fe);
drawingContext.DrawRectangle(visualBrush,
null,
new Rect(new Point(0,0),new Point(size.Width,size.Height)));
}
rtb.Render(drawingVisual);
var jpgEncoder = new JpegBitmapEncoder();
jpgEncoder.Frames.Add(BitmapFrame.Create(rtb));
using(FileStream fs=new FileStream(jpgFile,FileMode.Create))
{
jpgEncoder.Save(fs);
MessageBox.Show($"Saved in {System.IO.Path.GetFullPath(jpgFile)}");
OpenJpgFileViaProcess(jpgFile);
}
}
![image]()
![image]()
![image]()
//xaml
<Window x:Class="WpfApp40.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp40"
mc:Ignorable="d"
WindowState="Maximized"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ItemsControl ItemsSource="{Binding ElpsCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Width="{Binding Width}"
Height="{Binding Height}"
Fill="{Binding ElpColor}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ContextMenu>
<ContextMenu>
<MenuItem Header="ReGenerate Ellipses"
Command="{Binding ReGenerateEllipsesCommand}"/>
<MenuItem Header="Save As Jpg"
Command="{Binding SaveAsJpgCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContextMenu}},
Path=PlacementTarget}"/>
</ContextMenu>
</ItemsControl.ContextMenu>
</ItemsControl>
</Grid>
</Window>
//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp40
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var vm = new MainVM();
this.DataContext=vm;
}
}
public class MainVM : INotifyPropertyChanged
{
private int dpiFactor = 2;
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler!=null)
{
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
private ObservableCollection<ElpModel> elpsCollection;
public ObservableCollection<ElpModel> ElpsCollection
{
get
{
return elpsCollection;
}
set
{
if (value!=elpsCollection)
{
elpsCollection=value;
OnPropertyChanged(nameof(ElpsCollection));
}
}
}
public MainVM()
{
InitData();
}
private void InitData()
{
double maxWidth = SystemParameters.FullPrimaryScreenWidth-100;
double maxHeight = SystemParameters.FullPrimaryScreenHeight-100;
Random rnd = new Random();
ElpsCollection=new ObservableCollection<ElpModel>();
List<Color> colorsList = new List<Color>();
colorsList.Add(Colors.Red);
colorsList.Add(Colors.Green);
colorsList.Add(Colors.Blue);
colorsList.Add(Colors.Yellow);
colorsList.Add(Colors.Black);
colorsList.Add(Colors.Gray);
colorsList.Add(Colors.Gold);
colorsList.Add(Colors.Cyan);
colorsList.Add(Colors.Magenta);
colorsList.Add(Colors.DarkBlue);
colorsList.Add(Colors.Purple);
int colorsCount = colorsList.Count;
for (int i = 0; i<20; i++)
{
ElpsCollection.Add(new ElpModel()
{
Width=100,
Height=100,
X=rnd.Next(50, (int)maxWidth),
Y=rnd.Next(50, (int)maxHeight),
ElpColor=new SolidColorBrush(colorsList[i%colorsCount])
});
}
}
private ICommand saveAsJpgCommand;
public ICommand SaveAsJpgCommand
{
get
{
if (saveAsJpgCommand==null)
{
saveAsJpgCommand = new DelCommand(SaveAsJpgCommandExecuted);
}
return saveAsJpgCommand;
}
}
private void SaveAsJpgCommandExecuted(object? obj)
{
var fe = obj as FrameworkElement;
if(fe==null)
{
return;
}
string jpgFile = $"ItemsControl_{DateTime.Now.ToString("yyyyMMddmmHHssffff")}.jpg";
SaveFrameworkElementAsPicture(fe, jpgFile);
}
private void SaveFrameworkElementAsPicture(FrameworkElement fe,string jpgFile,int dpi=96)
{
Size size = new Size(fe.ActualWidth, fe.ActualHeight);
RenderTargetBitmap rtb=new RenderTargetBitmap(
(int)(size.Width * dpiFactor),
(int)(size.Height * dpiFactor),
dpi*dpiFactor,
dpi*dpiFactor,
PixelFormats.Pbgra32);
DrawingVisual drawingVisual=new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
VisualBrush visualBrush = new VisualBrush(fe);
drawingContext.DrawRectangle(visualBrush,
null,
new Rect(new Point(0,0),new Point(size.Width,size.Height)));
}
rtb.Render(drawingVisual);
var jpgEncoder = new JpegBitmapEncoder();
jpgEncoder.Frames.Add(BitmapFrame.Create(rtb));
using(FileStream fs=new FileStream(jpgFile,FileMode.Create))
{
jpgEncoder.Save(fs);
MessageBox.Show($"Saved in {System.IO.Path.GetFullPath(jpgFile)}");
OpenJpgFileViaProcess(jpgFile);
}
}
private void OpenJpgFileViaProcess(string jpgFile)
{
Process.Start(new ProcessStartInfo
{
FileName= jpgFile,
UseShellExecute=true
});
}
private ICommand reGenerateEllipsesCommand;
public ICommand ReGenerateEllipsesCommand
{
get
{
if(reGenerateEllipsesCommand == null)
{
reGenerateEllipsesCommand=new DelCommand(ReGenerateEllipsesCommandExecuted);
}
return reGenerateEllipsesCommand;
}
}
private void ReGenerateEllipsesCommandExecuted(object? obj)
{
InitData();
}
}
public class ElpModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propName = "")
{
var handler = PropertyChanged;
if (handler!=null)
{
handler?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
private double width;
public double Width
{
get
{
return width;
}
set
{
if (value!=width)
{
width=value;
OnPropertyChanged(nameof(Width));
}
}
}
private double height;
public double Height
{
get
{
return width;
}
set
{
if (value!=height)
{
height=value;
OnPropertyChanged(nameof(Height));
}
}
}
private double x;
public double X
{
get
{
return x;
}
set
{
if (value!=x)
{
x=value;
OnPropertyChanged(nameof(X));
}
}
}
private double y;
public double Y
{
get
{
return y;
}
set
{
if (value!=y)
{
y=value;
OnPropertyChanged(nameof(Y));
}
}
}
private SolidColorBrush elpColor;
public SolidColorBrush ElpColor
{
get
{
return elpColor;
}
set
{
if (value!=elpColor)
{
elpColor=value;
OnPropertyChanged(nameof(ElpColor));
}
}
}
}
public class DelCommand : ICommand
{
private readonly Action<object?> execute;
private readonly Predicate<object?> canExecute;
public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue = null)
{
execute=executeValue;
canExecute=canExecuteValue;
}
public event EventHandler? CanExecuteChanged
{
add
{
CommandManager.RequerySuggested+=value;
}
remove
{
CommandManager.RequerySuggested-=value;
}
}
public bool CanExecute(object? parameter)
{
return canExecute==null ? true : canExecute(parameter);
}
public void Execute(object? parameter)
{
execute(parameter);
}
}
}