How to set multiple canvas in scroll viewer in wpf? - wpf

I want to set an image in a canvas control and have 20 canvases that I am creating by using a loop. The problem is that when I want to add all those canvas items in to a scroll viewer it does not work. Here is my code:
private void CreateAndShowCanvas()
{
List<Canvas> list = new List<Canvas>();
for (int i = 0; i < 20; i++)
{
Canvas myCanvas1 = new Canvas();
myCanvas1.Background = new SolidColorBrush(Colors.Transparent);
myCanvas1.Height = 235;
myCanvas1.Width = 626;
//Canvas.SetZIndex(myCanvas1, 4);
Image MainImage = new Image();
MainImage.Width = 275;
MainImage.Height = 235;
BitmapImage mi = new BitmapImage(new Uri("select_1.png", UriKind.Relative));
MainImage.Source = mi;
Canvas.SetTop(MainImage, 0);
Canvas.SetLeft(MainImage, 0);
myCanvas1.Children.Add(MainImage);
Image SeparatorImage = new Image();
BitmapImage si = new BitmapImage(new Uri("Sentre Seprator.png", UriKind.Relative));
SeparatorImage.Height = 270;
SeparatorImage.Source = si;
Canvas.SetTop(SeparatorImage, -5);
Canvas.SetLeft(SeparatorImage, 310);
myCanvas1.Children.Add(SeparatorImage);
Image SecondImage = new Image();
SecondImage.Width = 275;
SecondImage.Height = 235;
BitmapImage sci = new BitmapImage(new Uri("select_2.png", UriKind.Relative));
SecondImage.Source = sci;
Canvas.SetTop(SecondImage, 0);
Canvas.SetLeft(SecondImage, 350);
myCanvas1.Children.Add(SecondImage);
list.Add(myCanvas1);
}
scv.Content = list;
}
and in XML:
<Window x:Class="WpfApplication1.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>
<ScrollViewer Name="scv" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled" Margin="60,40,59,46" Opacity="99" Background="Transparent" />
</Grid>
</Window>
and when I run it, it only shows ("Collection"). Please help me out, thanks in advance...

Should you not just be using a ListBox with an ItemTemplate that has Canvases inside it instead? There must be an easier way to do whatever you are trying to achieve than creating 20 canvases manually.
Here's some reading to do with ListBoxes.

A ScrollViewer can hold just a single child, so you need another panel type like a Grid or StackPanel which holds your canvases.
<Grid>
<ScrollViewer Name="scv" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled" Margin="60,40,59,46" Opacity="99" Background="Transparent">
<StackPanel Name="stp" />
</ScrollViewer>
</Grid>
Add canvases to stp instead.

Related

WPF Screen Capture doesn't include title bar

I implemented the code in the first answer to this question and it works great except that it doesn't include the title bar, which is a must for my needs. Does anybody have any idea what I'm doing wrong?
I've updated my example to show all the other commented out attempts that failed.
Here's my code:
Window shellView = Application.Current.MainWindow;
Rect bounds = VisualTreeHelper.GetDescendantBounds(shellView);
//Rect bounds = new Rect(new Size(shellView.ActualWidth, shellView.ActualHeight));
//Rect bounds = shellView.RestoreBounds;
//Rect bounds = VisualTreeHelper.GetContentBounds(shellView);
//Rect bounds = new Rect(new Size(VisualTreeHelperEx.FindDescendantByType<Window>(shellView).ActualWidth,
// VisualTreeHelperEx.FindDescendantByType<Window>(shellView).ActualHeight));
RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
DrawingVisual visual = new DrawingVisual();
string fileName = $#"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Screen_Capture.png";
if (_dialogService.ShowSaveFileDialog(ref fileName, "PNG Files | *.png"))
{
using (DrawingContext context = visual.RenderOpen())
{
VisualBrush visualBrush = new VisualBrush(shellView);
context.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));
}
renderTarget.Render(visual);
PngBitmapEncoder bitmapEncoder = new PngBitmapEncoder();
bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
using (Stream stm = File.Create(fileName))
{
bitmapEncoder.Save(stm);
}
}
And at XAMIMAX's request, what I can share of the XAML with names changed:
<Window x:Class="MyProject.Shell.Views.Shell.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ap="clr-namespace:MyProject.Common.Support.AttachedProperties;assembly=MyProject.Common.Support"
xmlns:controls="clr-namespace:MyProject.Common.Support.Controls;assembly=MyProject.Common.Support"
xmlns:converters="clr-namespace:MyProject.Common.Support.Converters;assembly=MyProject.Common.Support"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dts="clr-namespace:MyProject.Common.Support.DataTemplateSelectors;assembly=MyProject.Common.Support"
xmlns:enums="clr-namespace:MyProject.Shell.Enums"
xmlns:enums1="clr-namespace:MyProject.Common.Support.Enums;assembly=MyProject.Common.Support"
xmlns:ikriv="clr-namespace:MyProject.Common.Support.AttachedProperties;assembly=MyProject.Common.Support"
xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:m="clr-namespace:MyProject.Common.Support.MarkupExtensions;assembly=MyProject.Common.Support"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resources="clr-namespace:MyProject.Shell.Views.Shell.Resources"
xmlns:ss="clr-namespace:MyProject.Common.Support.StyleSelectors;assembly=MyProject.Common.Support"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:views="clr-namespace:MyProject.NotificationModule.Client.Views;assembly=MyProject.NotificationModule.Client"
xmlns:constants="clr-namespace:MyProject.Shell"
x:Name="shell"
Title="{Binding MyProjectApplicationTitle}"
Width="1024"
Height="768"
MinWidth="800"
MinHeight="600"
Background="{DynamicResource PrimarySolidColorBrush}"
Icon="/Resources/Embedded/MyProject.ico"
mc:Ignorable="d">
<controls:LocalizationScope.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.Children>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NavigationBarWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
MinWidth="38"
MaxWidth="400" />
</Grid>
</Grid.Children>
</Grid>
</controls:LocalizationScope.Content>
</Window>
I hope that's enough of the XAML to help. I also tried the example at this link Generating a screenshot of a WPF window, but got the same results: no title bar.
Thanks to the link that #Clemens sent me to, I was able to use some of the code on that page to come up with this working method. It grabs a few pixels more that the active window, but that works for me!
private void TakeScreenshot()
{
var rect = new Rect();
GetWindowRect(GetForegroundWindow(), ref rect);
var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
var result = new Bitmap(bounds.Width, bounds.Height);
using (var graphics = Graphics.FromImage(result))
{
graphics.CopyFromScreen(new System.Drawing.Point(bounds.Left, bounds.Top), System.Drawing.Point.Empty, bounds.Size);
}
string fileName = $#"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Screen_Capture.png";
if (_dialogService.ShowSaveFileDialog(ref fileName, "PNG Files | *.png"))
{
result.Save(fileName, ImageFormat.Png);
_dialogService.ShowInfoDialog(_localizationService["Shell.Views.Shell.HelpMenu.ScreenshotSaved"] + $"{fileName}");
}
}

mouse wheel event is not getting executed

I am trying to use canvas inside windows form and zoom and pan that canvas for that first i put element host and then put canvas inside it and then put picture box in canvas and then trying to zoom canvas i have tried various ways but event of any control does not executed i have also written all mouse wheel events but no one is executed so please suggest me solution below is my code for adding controls and mouse wheel events
elementHost1.Height = picVarify.Height;
elementHost1.Width = picVarify.Width;
elementHost1.Location = picVarify.Location;
touchcanvas = new System.Windows.Controls.Canvas();
WindowsFormsHost hst = new WindowsFormsHost();
hst.Name = "Host";
hst.Child = picVarify;
hst.Height = picVarify.Height;
hst.Width = picVarify.Width;
touchcanvas.Height = picVarify.Height;
touchcanvas.Width = picVarify.Width;
touchcanvas.Children.Add(hst);
zm = new ZoomAndPan.ZoomAndPanControl();
zm.Name = "zm";
zm.Content = touchcanvas;
zm.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(zoomAndPanControl_MouseWheel);
elementHost1.Child = zm;
touchcanvas.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(touchcanvas_MouseWheel);
hst.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(hst_MouseWheel);
picVarify.MouseWheel += new MouseEventHandler(picverify_MouseWheel);
here is the code that's working fine for me. I added canvas inside a canvas and set background property of both canvases.
XAML
<Window x:Class="WpfStack.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="rootGrid" Margin="10,0,0.4,3.8">
<Canvas Name="BaseCanvas" Background="AliceBlue" Margin="10,0,0,10">
</Canvas>
</Grid>
Code
public MainWindow()
{
InitializeComponent();
Canvas touchcanvas = new System.Windows.Controls.Canvas();
touchcanvas.Height =100;
touchcanvas.Width = 100;
touchcanvas.Background = Brushes.Transparent;
touchcanvas.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(touchcanvas_MouseWheel);
BaseCanvas.Children.Add(touchcanvas);
BaseCanvas.Background = Brushes.Transparent;
}
public void touchcanvas_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs args)
{
args.Handled = true;
}

How to use Vlc.DotNet in WPF?

I am trying to use VLC in WPF via Vlc.DotNet. I have been successful in getting Vlc.DotNet to work in Winforms, but thus far unsuccessful with WPF.
I get no errors, but I also get no video... just a blank white pane.
Here is my very simple XAML:
<Window x:Class="VLC.Wpf.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" Closing="Window_Closing">
<Grid x:Name="Grid1">
</Grid>
</Window>
And here is the codebehind I use to insert and start the Vlc Wpf control.
public MainWindow()
{
VlcContext.LibVlcDllsPath = CommonStrings.LIBVLC_DLLS_PATH_DEFAULT_VALUE_AMD64;
VlcContext.LibVlcPluginsPath = CommonStrings.PLUGINS_PATH_DEFAULT_VALUE_AMD64;
VlcContext.StartupOptions.IgnoreConfig = true;
VlcContext.Initialize();
InitializeComponent();
var vlcPlayer = new VlcControl();
var media = new LocationMedia("rtsp://admin:12345#192.168.42.200:554/MediaInput/h264");
Grid1.Children.Add(vlcPlayer);
var vlcBinding = new Binding("VideoSource");
vlcBinding.Source = vlcPlayer;
var vImage = new Image();
vImage.SetBinding(Image.SourceProperty, vlcBinding);
var vBrush = new VisualBrush();
vBrush.TileMode = TileMode.None;
vBrush.Stretch = Stretch.Uniform;
vBrush.Visual = vImage;
Grid1.Background = vBrush;
vlcPlayer.Play();
}
Does anyone see anything wrong with this?
Using Vlc 2.1.5 win32
You haven't set vlcPlayer's Media property.
var vlcPlayer = new VlcControl();
var media = new LocationMedia("rtsp://admin:12345#192.168.42.200:554/MediaInput/h264");
vlcPlayer.Media = media; //add this
Btw, you don't need to add vlcPlayer to Grid1.

Programmatically add Panorama Items

I am working on windows Phone 7.5 App and I want to display a list of images programmatically in panorama control.I have the xaml
<!--Panorama item three-->
<controls:PanoramaItem x:Name="DiaPanorama" Header="History" FontSize="20">
and the code part is -
PanoramaItem p = new PanoramaItem();
Image i = new Image();
i.Source = new BitmapImage(new Uri("/web.png", UriKind.Relative));
p.Margin = new Thickness(0, -10, 0, -2);
p.Content = i;
DiaPanorama.Items.Add(p);
but it's showing an error that Microsoft.Phone.Control.PanoramaItem does not contain defination for Items.
How can i solve this problem?Please help.
Is there any other approach for adding images programmatically in panorama?
According to your sample, you're trying to add a new PanoramaItem to an existing PanoramaItem. That won't work - you'd need to add the new PanoramaItem to the parent controls:Panorama object.
When adding multiple items to a PanoramaItem or PivotItem, you must add a containing element first such as a Grid, StackPanel or Canvas
In XAML
<controls:Panorama x:Name="Panorama" Title="Panorama Control">
<controls:PanoramaItem x:Name="Item1" Header="Item 1">
<StackPanel>
<TextBlock Text="Hello World" />
<Image Source="Background.png" />
</StackPanel>
</controls:PanoramaItem>
</controls:Panorama>
In C#
var item = new PanoramaItem();
var panel = new StackPanel();
var text = new TextBlock();
text.Text = "HelloWorld";
panel.Children.Add(text);
var image = new Image();
image.Source = new BitmapImage(new Uri("Background.png", UriKind.Relative));
panel.Children.Add(image);
item.Content = panel;
Panorama.Items.Add(item); // Add to existing panorama control

Wpf dynamic design with Grid and data binding

I am creating dynamic UI using from code.I am adding grid to the Page using for loop,in multiple rows and 4 columns,so it takes time to load UI on Page.I want to load each child Grid lazily, I don't know how to do it, please help.
here is XAML file
<ScrollViewer Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CanContentScroll="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0 0 0 0">
<Grid x:Name="mainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10" Width="Auto">
</Grid>
</ScrollViewer>
and this is pseudo code from .cs file
for (int column = 0; column < dsMacDtls.Tables[0].Rows.Count; column++)
{
grid = new Grid();
grid.Width = 108;
grid.Height = 108;
if (column % 4 == 0)
{
mainGrid.RowDefinitions.Add(new RowDefinition());
}
else
{
mainGrid.RowDefinitions.Add(new RowDefinition());
}
box = new CheckBox();
TextBlock tb = new TextBlock();
tb.Text = "abcd";
box.Content = tb;
grid.Children.Add(box);
ImageBrush myBrush = new ImageBrush();
image = new Image();
image.Source = new BitmapImage(new Uri("abcd.png"));
grid.Background = myBrush;
Grid.SetColumn(grid, 0);
Grid.SetRow(grid, i);
Border br = new Border();
br.BorderThickness = new Thickness(1);
br.BorderBrush = new SolidColorBrush(Colors.Gray);
Grid.SetColumn(br, 0);
Grid.SetRow(br, rowNumberofMachine);
br.Width = 108;
br.Height = 108;
grid.Children.Add(br);
mainGrid.Children.Add(grid);
}

Resources