wpf oxyplot PlotAreaBackground image - wpf

I want a colorful background. My code not work. Version OxyPlotWpf: 1.0.0-unstable2100. Date published: Tuesday, April 12, 2016 (4/12/2016)
Can not imagine what else you can write in detail, my questions not passed since the system thinks there is not enough detail, so I added the text (sorry)
What i have
What i want
My GrpahPhone.png
<Window x:Class="OxiPlotTest.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:OxiPlotTest"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
xmlns:oxy2="http://oxyplot.codeplex.com"
mc:Ignorable="d"
Title="MainWindow" Height="250" Width="750"
Background="#333333">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="200"/>
</Grid.RowDefinitions>
<oxy:Plot Grid.Row="0" x:Name="oxyPlot2" Title="" Margin="10" Background="Transparent" PlotAreaBorderThickness="0,0,0,1" PlotAreaBorderColor="#CCCCCC">
<oxy:Plot.Axes>
<oxy:LinearAxis Position="Left" Minimum="0" Maximum="100" MajorGridlineColor="#333333" MajorGridlineStyle="Solid" MajorGridlineThickness="1" MajorStep="25" MinorStep="25"
TickStyle="None" TextColor="#CCCCCC" FontSize="16" FontWeight="Bold" AxisDistance="5"/>
<oxy:LinearAxis Position="Bottom" Minimum="0" Maximum="5" MajorGridlineStyle="None" MajorStep="1" MinorStep="1"
TextColor="#CCCCCC" FontSize="16" FontWeight="Bold" TicklineColor="#CCCCCC"/>
</oxy:Plot.Axes>
<oxy:Plot.Series>
<oxy:LineSeries ItemsSource="{Binding Points}" Color="AliceBlue" StrokeThickness="4"/>
</oxy:Plot.Series>
</oxy:Plot>
</Grid>
public partial class MainWindow : Window
{
public IList<DataPoint> Points { get; private set; }
public MainWindow()
{
InitializeComponent();
Points = new List<DataPoint>
{
new DataPoint(0, 5),
new DataPoint(1, 40),
new DataPoint(2, 55),
new DataPoint(3, 80),
new DataPoint(4, 90),
new DataPoint(5, 50),
};
DataContext = this;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri("pack://application:,,,/OxiPlotTest;component/Resources/GraphFon.png", UriKind.Absolute);
bitmapImage.EndInit();
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapImage)bitmapImage));
var stream = new System.IO.MemoryStream();
encoder.Save(stream);
stream.Flush();
var image = new System.Drawing.Bitmap(stream);
var bitmap = new System.Drawing.Bitmap(image);
var bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
bitmap.Dispose();
var brush = new ImageBrush(bitmapSource);
oxyPlot2.PlotAreaBackground = brush;
}
}

I made 5 different List Points by color and added LineSeries

Related

Add controls into textblock wpf in code behind

How can i convert this UI into code behind wpf
<TextBlock x:Name="tblImgCorrectAnswer">
<Span>Hello</Span>
<Span Style="{DynamicResource FontMSMincho}">て</Span>
<InlineUIContainer BaselineAlignment="Center">
<TextBlock>
<Image Source="Images/icon.ico" Width="40" Height="40"/>
</TextBlock>
</InlineUIContainer>
</TextBlock>
I cann't anyway to add item control into textblock control or TextBlock control into InlineUIContainer control by using code-behind.
Thanhks.
The result like This
Code Behind
var textBlock = new TextBlock();
var inlineHello = new Span();
inlineHello.Inlines.Add("Hello");
var inlineJSighn = new Span();
inlineJSighn.Inlines.Add(" JSighn");
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/Images/Koala.jpg", UriKind.Absolute);
logo.EndInit();
var inlineUiContainer = new InlineUIContainer(new Image { Source = logo });
inlineUiContainer.BaselineAlignment = BaselineAlignment.Center;
textBlock.Inlines.Add(inlineHello);
textBlock.Inlines.Add(inlineJSighn);
textBlock.Inlines.Add(inlineUiContainer);
LayoutRoot.Children.Add(textBlock);
Xaml
<Window x:Class="AddChildrenToGrinInCode.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="LayoutRoot"/></Window>

DrawingContext.PushOpacityMask() with BitmapImage does not work

I want to take a given BitmapImage and use its grayscale/black-and-white representation as an opacity mask on a DrawingContext.
I got far enough to do the color conversion, so I ended up with the follwing state of a demo application:
Method on ViewModel:
public void Demo()
{
var width = 400;
var height = 400;
var target = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
var target2 = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
var drawingVisual = new DrawingVisual();
var drawingVisual2 = new DrawingVisual();
using (var drawingContext = drawingVisual.RenderOpen())
{
var bitmapImage = new BitmapImage(new Uri(#"pack://application:,,,/WarningFilled.png"));
using (var drawingContext2 = drawingVisual2.RenderOpen())
{
drawingContext2.DrawImage(bitmapImage, new Rect(0, 0, width, height));
}
target2.Render(drawingVisual2);
var mask = target2.ToGrayscale();
this.Mask = mask;
drawingContext.PushOpacityMask(new ImageBrush(mask));
drawingContext.DrawRectangle(Brushes.Red, null, new Rect(0, 0, width, height));
// drawingContext.Pop();
}
target.Render(drawingVisual);
this.Rendered = target;
}
View:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<wpfApplication1:MainViewModel></wpfApplication1:MainViewModel>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderThickness="2" BorderBrush="Blue" HorizontalAlignment="Center">
<Image Source="{Binding Rendered}" Width="400" Height="400"></Image>
</Border>
<Border Grid.Column="1" BorderThickness="2" BorderBrush="Green" HorizontalAlignment="Center">
<Image Source="{Binding Mask}" Width="400" Height="400"></Image>
</Border>
</Grid>
Running the demo application produces this:
I expected the red rectangle on the left to reflect the opacity mask pushed onto the DrawingContext before drawing the actual rectangle.
The image you see on the right is the BitmapImage after the color conversion, right before it is pushed as an opacity mask. As I mentioned before I also tried it with the black/white conversion, but even with only two colors there's no effect.
I've tried many similar setups and scenarios, but I don't get the opacity mask to work.
From the Opacity Masks Overview article on MSDN (emphasis mine):
To create an opacity mask, you apply a Brush to the OpacityMask
property of an element or Visual. The brush is mapped to the element
or visual, and the opacity value of each brush pixel is used to
determine the resulting opacity of each corresponding pixel of the
element or visual.
The color values of the pixel are ignored.

Simple databinding between slider and object to update a drawing in WPF

I have a specific need to use System.Drawing.Graphics to use as as ImageSource for an Image control. That graphics is to be updated by a slider, whose Value is to be data-bound to an object that acts as a model to build the drawing.
I have set up a minimal working version of what I want to accomplish, and have created as much "Binding Infrastructure" as I could, but have stopped where things started to get confusing for me. My code has just the MainWindow (XAML and code behind) and a Radius class:
MainWindow:
<Window x:Class="MinimalUpdateableDrawing.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
WindowState="Maximized">
<DockPanel>
<Slider x:Name="SizeSlider" DockPanel.Dock="Bottom" />
<Image x:Name="figure" Width="800" Height="600" />
</DockPanel>
</Window>
MainWindow codebehind:
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;
namespace MinimalUpdateableDrawing {
public partial class MainWindow : Window {
Radius radius_instance;
public MainWindow() {
InitializeComponent();
radius_instance = new Radius();
this.Loaded +=new RoutedEventHandler(DrawCircle);
}
void DrawCircle(object sender, RoutedEventArgs e) {
int radius = radius_instance.Value;
using (var bmp = new Bitmap((int)figure.Width, (int)figure.Height)) {
using (var g = Graphics.FromImage(bmp)) {
g.FillEllipse(System.Drawing.Brushes.Blue,
(int)figure.Width/2-radius,
(int)figure.Height/2-radius,
radius*2, radius*2);
}
using(MemoryStream ms = new MemoryStream()) {
bmp.Save(ms, ImageFormat.Bmp);
ms.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = ms;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
figure.Source = bitmapImage;
}
}
}
}
}
Radius class:
using System;
using System.ComponentModel;
namespace MinimalUpdateableDrawing
{
class Radius : INotifyPropertyChanged {
int _value = 100;
public int Value {
get { return _value; }
set {
_value = value;
OnPropertyChanged("Value");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string p) {
throw new NotImplementedException();
}
}
}
If anyone could suggest what I should do to implement the binding between SizeSlider and radius_instance.Value, so that when I move the slider the image updates, that would get me going!
If you were simply drawing an ellipse, I'd recommend binding both the slider's value and an Ellipse object to the object that stores the value in question. You can see more about drawing with Wpf at http://msdn.microsoft.com/en-us/library/ms747393.aspx.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Ellipse Height="{Binding Radius}" Width="{Binding Radius}" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" />
<Slider Value="{Binding Radius}" Grid.Row="1" Minimum="0" Maximum="200" />
</Grid>
With that said, if the drawing was more complex, you may want to consider using an IValueConverter to adapt the value into a drawing you could use...for example:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:EllipseConverter x:Key="EllipseConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="{Binding Radius, Converter={StaticResource EllipseConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None" />
<Slider Value="{Binding Radius}" Grid.Row="1" Minimum="0" Maximum="200" />
</Grid>
</Window>
IValueConverter:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace WpfApplication1
{
class EllipseConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return null;
int radius = (int)value;
int diameter = radius * 2;
using (var bmp = new System.Drawing.Bitmap(diameter, diameter))
{
using (var g = Graphics.FromImage(bmp))
{
g.FillEllipse(System.Drawing.Brushes.Blue,
0,
0,
diameter,
diameter);
}
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, ImageFormat.Bmp);
ms.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = ms;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

Canvas print - wpf

I used these code in order to print out the UI. Printing out is working, but if the size of paper is over, the UI cuts off in the middle of a canvas.
Is there any possible way not to be cut off in the middle?
<--cs code-->
PrintDialog dialog = new PrintDialog();
dialog.PrintVisual(lst , "print");
<--Xaml -->
<ListView Name="lst">
<Grid Name="grdPrint">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Canvas Grid.Row="0" >
.......
</Canvas>
<HListBox x:Name="lstImage" ItemsSource="{Binding IMG, Mode=TwoWay}" Grid.Row="1" IsHitTestVisible="True">
<HListBox.ItemTemplate>
<DataTemplate>
<HImage Margin="0" Width="590" Height="590" Stretch="Fill" Source="{Binding IMG_PATH_NM, Converter={StaticResource StrUriConverter}}" Tag="{Binding IMG_PATH_NM}">
</HImage>
</DataTemplate>
</HListBox.ItemTemplate>
<HListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" IsHitTestVisible="True"/>
</ItemsPanelTemplate>
</HListBox.ItemsPanel>
</HListBox>
</Grid>
</ListView>
This method will print the canvas to PNG file.
public void ExportToPNG(string imgpath, Canvas surface)
{
Uri path = new Uri(imgpath);
if (path == null)
return;
Transform transform = surface.LayoutTransform;
surface.LayoutTransform = null;
Size size = new Size(surface.Width, surface.Height);
surface.Measure(size);
surface.Arrange(new Rect(size));
RenderTargetBitmap renderBitmap =
new RenderTargetBitmap(
(int)size.Width,
(int)size.Height,
96d,
96d,
PixelFormats.Pbgra32);
renderBitmap.Render(surface);
using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
surface.LayoutTransform = transform;
}
You could create an BitmapImage (see RenderTargetBitmap to create a bitmap from an element). This bitmap can then be saved as a JPEG file and manipulated using GDI+ (System.Image).

BarChart Values not updating

I am trying to develop a application where-in I a want to generate a random number after every three seconds, insert that number into a listBox and using DataTemplate display the ListBox as a rectangle.
This is for reference.
Now the problem is that I have used a DispatcherTimer which 'ticks' after 3 seconds but the rectangle is not updated.
I am posting my XAML and .cs code. Any hints ?
namespace ListBarGraph
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer dt = new DispatcherTimer();
DataFactory df = new DataFactory();
public MainWindow()
{
InitializeComponent();
dt.Tick += new EventHandler(dt_Tick);
dt.Interval = new TimeSpan(0, 0, 3);
dt.Start();
this.PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
}
void dt_Tick(object sender, EventArgs e)
{
df.GetData();
}
}
public class DataFactory
{
int number = 0;
public IEnumerable<int> GetData()
{
Random random = new Random();
number = random.Next(0, 100);
return new int[] { 0, number };
}
}
}
<Window x:Class="ListBarGraph.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ListBarGraph"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ObjectDataProvider x:Key="someData" ObjectType="{x:Type local:DataFactory}" MethodName="GetData" />
<DataTemplate x:Key="BarChartItemsTemplate">
<Border Width="300" Height="50">
<Grid>
<Rectangle Fill="Red" StrokeThickness="2" Height="40" Width="{Binding}" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="1.5"/>
</Rectangle.LayoutTransform>
</Rectangle>
</Grid>
</Border>
</DataTemplate>
<ItemsPanelTemplate x:Key="BarChartItemsPanel">
<VirtualizingStackPanel IsItemsHost="True">
<VirtualizingStackPanel.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<ScaleTransform ScaleX="-1" ScaleY="1"/>
</TransformGroup>
</VirtualizingStackPanel.LayoutTransform>
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Source={StaticResource someData}}" ItemTemplate="{DynamicResource BarChartItemsTemplate}" ItemsPanel="{DynamicResource BarChartItemsPanel}"/>
</Grid>
</Window>
Your XAML is bound to one instance of DataFactory as created by the ObjectProvider, whilst your code-behind creates another instance altogether, to which the UI is not bound.
Try this to get you started. In your XAML, remove the ObjectProvider and change your ListBox to:
<ListBox ItemsSource="{Binding}" ...
Inside dt_Tick, do this:
this.DataContext = df.GetData();

Resources