I'm trying to create a simple grid in a Windows 8 Universal app.
Below is my goal.
Row1Col1 Row1Col2 Row1Col3
Row2Col1 Row2Col2 Row2Col3
Row3Col1 Row3Col2 Row3Col3
<Grid x:Name="Grid1" HorizontalAlignment="Left" Height="217" Margin="557,135,0,0" Grid.Row="1" VerticalAlignment="Top" Width="433">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
</Grid>
I'd like to set up even spaced rows and columns in XAML and add the Text labels in code.
Something like:
Grid.Row1.Col1.Text="Row1Col1";
Grid.Row1.Col2.Text="Row1Col2";
A short XAML snippet and piece of c# code would be helpful.
Here is my xaml so far.
Any help appreciated.
To add text to the different cells in the grid i've added TextBlocks and placed them appropriately:
<Page.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="40"/>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Name="r1c1" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r1c2" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r1c3" Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r2c1" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r2c2" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r2c3" Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r3c1" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r3c2" Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Name="r3c3" Grid.Row="2" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
As an example, I've altered my code behind to the following:
private int N = 3;
private TextBlock[,] gridText;
public MainPage()
{
this.InitializeComponent();
InitializeGridText();
MethodThatChangesText();
}
private void InitializeGridText()
{
gridText = new TextBlock[N, N];
gridText[0, 0] = r1c1;
gridText[0, 1] = r1c2;
gridText[0, 2] = r1c3;
gridText[1, 0] = r2c1;
gridText[1, 1] = r2c2;
gridText[1, 2] = r2c3;
gridText[2, 0] = r3c1;
gridText[2, 1] = r3c2;
gridText[2, 2] = r3c3;
}
void MethodThatChangesText()
{
// Some Logic Here
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
gridText[i, j].Text = String.Format("Row{0}Col{1}", i + 1, j + 1);
}
Depending on what you're trying to do, you can add your own logic and have this method get called in response to some event (e.g. button click...).
Related
I'm creating a Wizard to export DB tables into CSV.
I'm using Xceed Wizard and I need an Event in Next button. I want to validate the parameters before going to the next page when I click "Next", but I only can set CanSelectNextPage.
XAML code:
<xctk:WizardPage x:Name="PageBD1" PageType="Interior"
Title="{DynamicResource PageBD1Title}"
Description="{DynamicResource PageBD1Desc}"
NextPage="{Binding ElementName=PageBD2}"
PreviousPage="{Binding ElementName=Page1}"
CanSelectNextPage="False">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="tbBDInfoServer1" Text="{DynamicResource tbBDInfoServer1}" Grid.Row="0" Grid.Column="0" />
<TextBox x:Name="tbBDServer1" Grid.Row="0" Grid.Column="2" TextChanged="tbBD1_TextChanged"/>
<TextBlock x:Name="tbBDInfoName1" Text="{DynamicResource tbBDInfoName1}" Grid.Row="1" Grid.Column="0" Margin="0,10,0,0" />
<TextBox x:Name="tbBDName1" Grid.Row="1" Grid.Column="2" Margin="0,10,0,0" TextChanged="tbBD1_TextChanged"/>
<TextBlock x:Name="tbBDInfoUser1" Text="{DynamicResource tbBDInfoUser1}" Grid.Row="2" Grid.Column="0" Margin="0,10,0,0" />
<TextBox x:Name="tbBDUser1" Grid.Row="2" Grid.Column="2" Margin="0,10,0,0" TextChanged="tbBD1_TextChanged"/>
<TextBlock x:Name="tbBDInfoPwd1" Text="{DynamicResource tbBDInfoPwd1}" Grid.Row="3" Grid.Column="0" Margin="0,10,0,0" />
<PasswordBox x:Name="tbBDPwd1" Grid.Row="3" Grid.Column="2" Margin="0,10,0,0"/>
</Grid>
</xctk:WizardPage>
C# code:
private void tbBD1_TextChanged(object sender, TextChangedEventArgs e)
{
if (tbBDServer1.Text != "" && tbBDName1.Text != "" && tbBDUser1.Text != "")
{
PageBD1.CanSelectNextPage = true;
}
else
PageBD1.CanSelectNextPage = false;
}
Thanks.
I'm creating a WPF program for editing PowerPoint presentation using Syncfusion library but whenever I run the program I see the memory increase when navigating from a page to another. I'm using WPF Application with a window that navigates between multiple pages.
How to encounter this problem actually?
Thank you.
These photos show where the leak is located :
PS: Please focus on the InitializeNonUITasks method in home.cs because that's where the leak is.
Home Page XAML:
<Page x:Class="ProjectSABX.Pages.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ProjectSABX.Pages"
xmlns:syncfusion="clr-namespace:Syncfusion.Windows;assembly=Syncfusion.Shared.Wpf"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
Width="1175" Height="660" KeyDown="Window_KeyDown"
Title="Home">
<Grid ShowGridLines="False" Margin="2,-2,-2,2">
<Grid Grid.Row="0" ShowGridLines="False">
<Grid.Background>
<SolidColorBrush Color="White" Opacity="0.5" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="2.5*"></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Height="52" Grid.Row="0" VerticalAlignment="Top" Fill="#FF80A20D"></Rectangle>
<TextBlock Name="titleBarTextBlock" Text="Aperçu" Height="40" Foreground="White" FontFamily="Segoe UI" FontWeight="Normal" Padding="15" FontSize="17.75" VerticalAlignment="Top" Grid.Row="0" HorizontalAlignment="Center"></TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0 15 10 0" Grid.Column="3" Grid.Row="0">
</StackPanel>
<Image Source="/Images/ViewerIcons/ppt__logo for header.png" Grid.Column="0" HorizontalAlignment="Left" Margin="15" VerticalAlignment="Top" Height="30"></Image>
</Grid>
<Grid Grid.Row="1" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="0*" />
<RowDefinition Height="445*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="59*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="8*" />
</Grid.ColumnDefinitions>
<Border ClipToBounds="True" BorderBrush="Black" BorderThickness=".7" Grid.Row="1" Grid.Column="0" Grid.RowSpan ="3" Margin="0,51,3,0">
<ScrollViewer Name="scrollViewer" Focusable="False" CanContentScroll="False" BorderBrush="Black" BorderThickness="1" HorizontalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="0" Grid.RowSpan ="3">
<Grid ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="9*" />
</Grid.ColumnDefinitions>
<StackPanel Name="stackpanel" Grid.Column="1" Width="170" />
</Grid>
</ScrollViewer>
</Border>
<Image Name ="centerSlideImage" Grid.Row="1" Grid.Column="1" Margin="0,57,5,19" />
<Canvas Name="loadingIndicatorCanvas" Visibility="Collapsed" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Margin="-250,-100,0,0">
<Canvas Canvas.Left="21.75" Canvas.Top="14" Height="81.302" Width="80.197">
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="5" />
<Setter Property="Height" Value="5" />
<Setter Property="Fill" Value="#FF9BD226" />
</Style>
</Canvas.Resources>
<Ellipse x:Name="_00" Canvas.Left="24.75" Canvas.Top="50" />
<Ellipse x:Name="_01" Canvas.Top="36" Canvas.Left="29.5" />
<Ellipse x:Name="_02" Canvas.Left="43.5" Canvas.Top="29.75" />
<Ellipse x:Name="_03" Canvas.Left="57.75" Canvas.Top="35.75" />
<Ellipse x:Name="_04" Canvas.Left="63.5" Canvas.Top="49.75" />
<Ellipse x:Name="_05" Canvas.Left="57.75" Canvas.Top="63.5" />
<Ellipse x:Name="_06" Canvas.Left="43.75" Canvas.Top="68.75" />
<Ellipse x:Name="_07" Canvas.Top="63.25" Canvas.Left="30" />
<Ellipse Stroke="{x:Null}" Width="39.5" Height="39.5" Canvas.Left="31.75" Canvas.Top="37" Fill="{x:Null}" />
</Canvas>
</Canvas>
<Grid Grid.Row="3" Grid.Column="1" ShowGridLines="False" Margin="0, -10">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*" />
<RowDefinition Height="20*" />
<RowDefinition Height="10*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="42*" />
<ColumnDefinition Width="45*" />
<ColumnDefinition Width="44*" />
<ColumnDefinition Width="45*" />
<ColumnDefinition Width="238*" />
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="40*" />
<ColumnDefinition Width="46*" />
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="45*" />
</Grid.ColumnDefinitions>
<Image Name="openDocument" Grid.Row="1" Grid.Column="1" Height="30" Width="30" Source="/Images/ViewerIcons/ppt__open.png" MouseDown="openDocument_MouseDown" MouseEnter="openDocument_MouseEnter" MouseLeave="openDocument_MouseLeave" Margin="0,5,7,4"></Image>
<Image Name="createPdfDocument" Grid.Row="1" Grid.Column="3" Height="30" Width="30" Source="/Images/ViewerIcons/ppt_pdf.png" MouseDown="createPdfDocument_MouseDown" MouseEnter="createPdfDocument_MouseEnter" MouseLeave="createPdfDocument_MouseLeave" Margin="0,5,8,4"></Image>
<DockPanel Grid.Row="1" Grid.Column="6" Grid.ColumnSpan="3">
<Image Name="prevDocument" Height="30" Width="30" Source="/Images/ViewerIcons/ppt__back.png" MouseDown="prevDocument_MouseDown" MouseEnter="prevDocument_MouseEnter" MouseLeave="prevDocument_MouseLeave"></Image>
<Label Name="lblPageDisplay" Height="30" MinWidth="30" FontFamily="Segoe UI" FontWeight="Bold" FontSize="18" VerticalAlignment="Center" VerticalContentAlignment="Center" Padding="35,0,0,0" Foreground="#646464" />
<Image Name="NextDocumentIconImage" Height="30" Width="30" Source="/Images/ViewerIcons/ppt__for.png" MouseDown="NextDocument_MouseDown" MouseEnter="NextDocument_MouseEnter" MouseLeave="NextDocument_MouseLeave" Margin="-10,0"></Image>
</DockPanel>
</Grid>
</Grid>
</Grid>
Home Page C#:
public Home()
{
InitializeComponent();
pdfBackroundWorker.DoWork += pdfBackroundWorker_DoWork;
pdfBackroundWorker.RunWorkerCompleted += pdfBackroundWorker_RunWorkerCompleted;
this.Background = new SolidColorBrush(Color.FromRgb(244, 244, 244));
filePath = "/Data/Template.pptx";
InitializeNonUITasks();
InitializeUITasks(filePath);
}
private void openDocument_MouseDown(object sender, MouseButtonEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "PowerPoint Presentations|*.pptx";
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
string filename = dlg.FileName;
filePath = filename;
slideNumber = 1;
displayBackroundWorker.RunWorkerAsync();
}
}
private void InitializeNonUITasks()
{
try
{
presentation = Presentation.Open(filePath);
}
catch (Exception exp)
{
MessageBox.Show("This PowerPoint Presentation cannot be opened properly, please contact support");
return;
}
slideImageSources.Clear();
thumbnailImageSource.Clear();
printImages.Clear();
currentSlideNumber = 0;
presentation.ChartToImageConverter = new ChartToImageConverter();
presentation.ChartToImageConverter.ScalingMode = Syncfusion.OfficeChart.ScalingMode.Best;
try
{
foreach (ISlide slide in presentation.Slides)
{
using (System.Drawing.Image image = slide.ConvertToImage(Syncfusion.Drawing.ImageType.Bitmap))
{
System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
printImages.Add(image.Clone() as System.Drawing.Image);
System.Drawing.Image newImage = image.GetThumbnailImage(170, 100, myCallback, System.IntPtr.Zero);
using (Stream ms = new MemoryStream())
{
newImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
var decoder = BitmapDecoder.Create(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
thumbnailImageSource.Add(decoder.Frames[0]);
}
using (Stream ms = new MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
var decoder = BitmapDecoder.Create(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
slideImageSources.Add(decoder.Frames[0]);
}
}
}
}
catch (Exception)
{
MessageBox.Show("This PowerPoint Presentation cannot be converted to images properly, please contact support");
return;
}
}
MainWindow XAML:
<Frame Grid.Column="1" Grid.Row="1" NavigationUIVisibility="Hidden" x:Name="Main" Source="./Pages/Home.xaml">
<Frame.Background>
<SolidColorBrush Color="#FFB0B0B0" Opacity="0.49" />
</Frame.Background>
</Frame>
MainWindow.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
private void ButtonClickHomePage(object sender, RoutedEventArgs e)
{
Main.Content = new Home();
}
}
Edit1: I tried to use the dispose() method for each object that implemented IDisposable, When navigating at first, the memory process decreases. then when I navigate from page to page it increases again.
It is hard to pinpoint the issue like this, but I do have some suggestions:
Usually it's about calling Dispose on all objects that implement the IDisposable interface.
check all object for the IDisposable interface and call Dispose() if it's available. E.g.: newImage.Dispose() (or use using)
Also, all the disposable objects in the lists printImages, thumbnailImageSource etc, should be disposed as well.
Also, I believe the decoder should be disposed as well, as well as the presentation, although I can be mistaken.
This will give you a good starting point - there might be more, but you should rule out and fix this first.
The loop is a likely suspect to be causing the memory increase.
Here's more info on IDisposable. Also, if you have implemented the IDisposable interface yourself - it's prety common to make a mistake with that as well. In that case you should double check it.
I'm creating a small numeric keyboard like those on our smartphones, when I press a key, the digit must be written in a TextBox.
This is where I have a problem, I can not update my TextBox when I press a button.
My window is decomposed into two frames of the same width, the keyboard is on the left frame and the TextBox on the right frame.
I call a method in my Clavier.xaml.cs page:
CallSection EtablissementAppel = new CallSection();
private void UpdateTextBox(string _UpdatePrefix, string _UpdateNumeroDestinataire)
{
EtablissementAppel.UpdateEtablissementAppel(_UpdatePrefix, _UpdateNumeroDestinataire);
}
Method in the CallSection.xaml.cs file:
public void UpdateEtablissementAppel(string p, string n)
{
string Numero = p + n;
EtablissementAppel.Text = Numero;
}
Code CallSection.xaml :
<TextBox x:Name="EtablissementAppel" Margin="5,5,5,5" PlaceholderText="ETABLISSEMENT D'APPEL" VerticalAlignment="Center" Grid.Column="0" Grid.ColumnSpan="2" Height="37"/>
Yet the TextBox does not want to update itself. Knowing that I can change its text anywhere in the file CallSection.xaml.cs but not in this method.
EDIT :
To give more details in relation to the first comments.
Method in CallSection.xaml.cs with a Debug.WriteLine() :
public void UpdateEtablissementAppel(string p, string n)
{
string Numero = p + n;
Debug.WriteLine(Numero);
EtablissementAppel.Text = Numero;
}
Here I can see in the debugger all my numbers tapped. But textbox doesn't update.
Debugger output :
12255
122552
1225525
12255255
122552555
CallSection.xaml :
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PhonieMartha"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Custom="using:Microsoft.UI.Xaml.Controls"
x:Class="PhonieMartha.CallSection"
mc:Ignorable="d" Loaded="Page_Loaded"
>
<Page.Resources>
<SolidColorBrush x:Key="GraySelected" Color="#FFA3A3A3"/>
<SolidColorBrush x:Key="GrayUnselected" Color="#33000000"/>
</Page.Resources>
<Page.Background>
<ThemeResource ResourceKey="ApplicationPageBackgroundThemeBrush"/>
</Page.Background>
<Grid x:Name="GrillePrincipale">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox x:Name="EtablissementAppel" Margin="5,5,5,5" PlaceholderText="ETABLISSEMENT D'APPEL" VerticalAlignment="Center" Grid.Column="0" Grid.ColumnSpan="2" Height="37"/>
<Rectangle x:Name="Call1" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="1" Grid.Column="0" Tapped="Call1_Tapped"/>
<Rectangle x:Name="Call2" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="1" Grid.Column="1" Tapped="Call2_Tapped"/>
<Rectangle x:Name="Call3" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="2" Grid.Column="0" Tapped="Call3_Tapped"/>
<Rectangle x:Name="Call4" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="2" Grid.Column="1" Tapped="Call4_Tapped"/>
<Rectangle x:Name="Call5" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="3" Grid.Column="0" Tapped="Call5_Tapped"/>
<Rectangle x:Name="Call6" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="3" Grid.Column="1" Tapped="Call6_Tapped"/>
<Rectangle x:Name="Call7" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="4" Grid.Column="0" Tapped="Call7_Tapped"/>
<Rectangle x:Name="Call8" HorizontalAlignment="Stretch" Margin="5,5,5,5" VerticalAlignment="Stretch" Fill="#33000000" FocusVisualPrimaryBrush="#FFE03535" Grid.Row="4" Grid.Column="1" Tapped="Call8_Tapped"/>
<TextBox x:Name="RenvoiAppel" Margin="5,5,5,5" PlaceholderText="RENVOI D'APPEL" VerticalAlignment="Stretch" Grid.Column="0" Grid.ColumnSpan="2" Height="37" Grid.Row="5" InputScope="Number"/>
<TextBox x:Name="MessageRecu" Margin="5,5,5,5" Text="" VerticalAlignment="Stretch" Grid.Column="2" Grid.Row="4" Grid.ColumnSpan="2"/>
<ToggleSwitch x:Name="ToggleSwitchRenvoiAppel" Margin="5,5,5,5" OnContent="On" OffContent="Off" Grid.Column="2" Grid.Row="5" HorizontalAlignment="Center" Toggled="ToggleSwitchRenvoiAppel_Toggled"/>
<TextBlock Grid.Column="3" Margin="5,5,5,5" Grid.Row="5" Text="PhonieMartha Rev1.0" TextWrapping="Wrap" VerticalAlignment="Stretch" TextAlignment="Center" FontSize="12"/>
</Grid>
</Page>
Here is the XAML code of the MainPage that contains the two frames :
<Page
x:Class="PhonieMartha.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PhonieMartha"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="GrilleMainPage">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Frame x:Name="CallsSection" Grid.Column="1"/>
<NavigationView x:Name="NavView" SelectionChanged="NavView_SelectionChanged" IsBackButtonVisible="Collapsed" PaneDisplayMode="Auto" CompactModeThresholdWidth="300" ExpandedModeThresholdWidth="550" Grid.Column="0">
<NavigationView.MenuItems>
<NavigationViewItem Icon="PhoneBook" Content="Annuaire général" Tag="AnnuaireGeneral"/>
<NavigationViewItem Icon="PhoneBook" Content="Annuaire personnel" Tag="AnnuairePersonnel"/>
<NavigationViewItem Content="Clavier" Tag="Clavier">
<NavigationViewItem.Icon>
<FontIcon Glyph="" FontFamily="Segoe MDL2 Assets"/>
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Content="Mode conférence" Tag="Conference">
<NavigationViewItem.Icon>
<FontIcon Glyph="" FontFamily="Segoe MDL2 Assets"/>
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Icon="Help" Content="Aide" Tag="Aide"/>
<NavigationViewItem Icon="Admin" Content="Mode instructeur" Tag="Instructeur"/>
</NavigationView.MenuItems>
<Frame x:Name="ContentFrame"/>
</NavigationView>
</Grid>
</Page>
You are creating a new instance of CallSection and then call the UpdateEtablissementAppel method of this one. This will obviously not affect the instance that you see on the screen. You need to get a reference to the existing instance and call its UpdateEtablissementAppel method.
You could use the following helper method to get a reference to the parent MainPage:
private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
var parent = VisualTreeHelper.GetParent(dependencyObject);
if (parent == null) return null;
var parentT = parent as T;
return parentT ?? FindParent<T>(parent);
}
And then cast the Content of the "CallsSection" Frame:
private void UpdateTextBox(string _UpdatePrefix, string _UpdateNumeroDestinataire)
{
MainPage mainPage = FindParent<MainPage>(this);
if (mainPage != null)
{
CallSection cellSection = mainPage.CallsSection.Content as CallSection;
if (cellSection != null)
cellSection.UpdateEtablissementAppel(_UpdatePrefix, _UpdateNumeroDestinataire);
}
}
You also need to make the Frame accessible from other classes. You can do this returning a reference to it from a public property of MainPage.xaml.cs, or by using the x:FieldModifier attribute directly in the XAML markup:
<Frame x:Name="CallsSection" x:FieldModifier="public" Grid.Column="1"/>
At the past, I can convert and save an usercontrol to an JPEG image with this code:
private string CreateBitmapImage(FrameworkElement usefulData, string name) // Tekli görev kartını masaüstünde oluşturmak için, resim yaratma fonksiyonu.
{
try
{
string fullFileName = string.Empty;
Size size = new Size(642, 416);
usefulData.Measure(size);
usefulData.Arrange(new Rect(size));
var rtb = new RenderTargetBitmap((int)usefulData.ActualWidth, (int)usefulData.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(usefulData);
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
SaveFileDialog dlg = new SaveFileDialog();
dlg.Title = "Görev kartını nereye kaydetmek istersiniz ?";
dlg.FileName = name; // Default file name
dlg.DefaultExt = ".jpg"; // Default file extension
dlg.Filter = "Resim Dosyası (.jpg)|*.jpg"; // Filter files by extension
dlg.OverwritePrompt = true;
var result = dlg.ShowDialog();
if (result == true && dlg.CheckPathExists == true)
{
fullFileName = System.IO.Path.Combine(dlg.FileName);
using (var filestream = new FileStream(fullFileName, FileMode.Create))
{
encoder.Save(filestream);
}
}
return fullFileName;
}
catch
{
MessageBox.Show("Tek görev kartını yaratırken bir hata oluştu.Lütfen yeniden deneyin.", "Hata", MessageBoxButton.OK, MessageBoxImage.Error);
return "";
}
}
Now, I'm converting my WPF project to UWP. However, I cannot find how I convert and save an usercontrol to an Jpeg image in UWP. Can you help me please ?
Thanks.
Update: My UserControl in UWP. As I explained at bottom, I got an exception if I try render the user control:
<UserControl
x:Class="AYOS_IDPrinter_UWP.TaskCard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AYOS_IDPrinter_UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="416"
d:DesignWidth="642" HorizontalAlignment="Center" VerticalAlignment="Center" RequestedTheme="Default">
<UserControl.Resources>
<SolidColorBrush x:Key="AuSupportColor" Color="#FFE5C97C"/>
</UserControl.Resources>
<Border x:Name="OutSketch" BorderThickness="2" BorderBrush="{StaticResource AuSupportColor}">
<Grid x:Name="MainGrid" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="NeedleArea" BorderThickness="0,0,0,2" Background="{StaticResource AUColor}" BorderBrush="{StaticResource AuSupportColor}">
<TextBlock x:Name="Label" TextWrapping="Wrap" Text="İğne Alanı / Needle Area" Foreground="White" TextAlignment="Center" Margin="0" VerticalAlignment="Center" FontFamily="Noto Sans" FontWeight="Normal"/>
</Border>
<Grid x:Name="Values" HorizontalAlignment="Stretch" Margin="10,10,10,10" VerticalAlignment="Stretch" Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="Header" Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="128"/>
<ColumnDefinition/>
<ColumnDefinition Width="128"/>
</Grid.ColumnDefinitions>
<Image x:Name="Logo1" Source="Images/AULogo.png" Margin="0" Grid.RowSpan="4" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Height="100"/>
<Image x:Name="Logo2" Source="Images/AnkudemLogo.png" Margin="0" Grid.RowSpan="4" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Height="100"/>
<TextBlock x:Name="Header_1" Grid.Column="1" Margin="0" TextWrapping="Wrap" Text="AYÖS" FontSize="28" TextAlignment="Center" FontWeight="Bold" Foreground="#FF284985" FontFamily="Noto Sans"/>
<TextBlock x:Name="Header_2" Grid.Column="1" Margin="0" TextWrapping="Wrap" Text="SINAV GÖREV KARTI" FontSize="24" TextAlignment="Center" Grid.Row="1" Foreground="#FF284985" FontFamily="Noto Sans"/>
<TextBlock x:Name="Header_3" Grid.Column="1" Margin="0" TextWrapping="Wrap" Text="EXAMINATION TASK CARD" FontSize="24" TextAlignment="Center" Grid.Row="2" Foreground="#FF284985" FontFamily="Noto Sans"/>
<TextBlock x:Name="DateText" Grid.Column="1" Margin="0" TextWrapping="Wrap" FontSize="22" TextAlignment="Center" Grid.Row="3" Foreground="#FF284985" Text="28 Mayıs 2016 – May 28, 2016" FontFamily="Noto Sans"/>
</Grid>
<Grid x:Name="Data" Grid.Row="1" Margin="0,18,0,-17">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="NameText" Margin="0,10,0,0" TextWrapping="Wrap" FontSize="32" TextAlignment="Center" Foreground="Red" Text="BERK BABADOĞAN" FontWeight="Bold" FontFamily="Noto Sans"/>
<TextBlock x:Name="TaskText" Margin="0,0,0,10" TextWrapping="Wrap" Text="Salon Başkanı" FontSize="28" TextAlignment="Center" Foreground="Black" Grid.Row="1" FontFamily="Noto Sans"/>
</Grid>
<Grid x:Name="Specs" Margin="10" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="SpecsH_1" Margin="0,0,5,0" TextWrapping="Wrap" Text="Sınav Yeri / Exam Area: " FontSize="20" Foreground="#FF343434" FontStyle="Italic" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Noto Sans"/>
<TextBlock x:Name="SpecsH_2" Margin="0,0,5,0" TextWrapping="Wrap" Text="Salon Adı / Hall Name:" FontSize="20" Foreground="#FF343434" Grid.Row="1" FontStyle="Italic" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Noto Sans"/>
<TextBlock x:Name="SpecsH_3" Margin="0,0,5,0" TextWrapping="Wrap" Text="Salon No / Hall Number:" FontSize="20" Foreground="#FF343434" Grid.Row="2" FontStyle="Italic" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Noto Sans"/>
<TextBlock x:Name="AreaText" Margin="5,0,0,0" TextWrapping="Wrap" Text="İstanbul" FontSize="20" Foreground="#FF343434" FontStyle="Italic" Grid.Column="1" VerticalAlignment="Center" FontFamily="Noto Sans"/>
<TextBlock x:Name="HallNameText" Margin="5,0,0,0" TextWrapping="Wrap" Text="A Blok 3. Kat Derslik 316" FontSize="20" Foreground="#FF343434" Grid.Row="1" FontStyle="Italic" Grid.Column="1" VerticalAlignment="Center" FontFamily="Noto Sans"/>
<TextBlock x:Name="HallNoText" Margin="5,0,0,0" TextWrapping="Wrap" Text="340111" FontSize="20" Foreground="#FF343434" Grid.Row="2" FontStyle="Italic" Grid.Column="1" VerticalAlignment="Center" FontFamily="Noto Sans"/>
</Grid>
</Grid>
</Grid>
</Border>
It is the code how I create an instance from my user control:
var item = new TaskCard(Name_TextBox.Text.ToUpper() + " " + Surname_TextBox.Text.ToUpper(), Task_TextBox.Text, ExamArea_TextBox.Text, HallName_TextBox.Text,HallNumber_TextBox.Text,DateConverter.Get(Date_Picker.Date.ToString())); // Creating card.
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(item); // Gives error here.
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
For converting, UWP app also has RenderTargetBitmap class for capturing a UIElement as an image source. For file saving, you could reference this turtorial. In UWP app we have FileSavePicker which is similar to SaveFileDialog. For example, a completed demo as follows:
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(elementToRender, 642,416);
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var savePicker = new FileSavePicker();
savePicker.DefaultFileExtension = ".png";
savePicker.FileTypeChoices.Add(".png", new List<string> { ".png" });
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.SuggestedFileName = "snapshot.png";
// Prompt the user to select a file
var saveFile = await savePicker.PickSaveFileAsync();
// Verify the user selected a file
if (saveFile == null)
return;
// Encode the image to the selected file on disk
using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
More details you could reference the official XAML render to bitmap sample.
Update:
Also add the XAML code section which use a UserControl for testing. What pass to the RenderAsync method should be the name of the Element you want to render.
<local:MyUserControl
x:Name="elementToRender"
Width="100"
Height="150" />
I did some researches why I can't render a TargetBitmap from code. I found a reason at this link:
You cannot save visual element which in code (offscreen) to image.
So, I foluna a new way to render my code based user control. I created my user control via code like this:
//Initializing task card.
var item = new TaskCard(Name_TextBox.Text.ToUpper() + " " + Surname_TextBox.Text.ToUpper(), Task_TextBox.Text, ExamArea_TextBox.Text, HallName_TextBox.Text, HallNumber_TextBox.Text, DateConverter.Get(Date_Picker.Date.ToString())); // Creating card.
After this, I added a custom popup-like element with this:
<Border x:Name="RingBorder" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{ThemeResource SystemControlBackgroundBaseHighRevealBorderBrush}" BorderThickness="2,2,2,2" RequestedTheme="Default" Visibility="Collapsed" >
<Grid x:Name="InnerGrid_Ring" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" RequestedTheme="Default" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid x:Name="WaiterRing_SecondRow" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock x:Name="LoadValue_Ring" Text="Lütfen bekleyin..." TextWrapping="Wrap" FontWeight="Normal" Margin="10,0,10,0" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Stretch" Grid.Column="1" Style="{StaticResource TitleTextBlockStyle}" />
<ProgressRing x:Name="Waiter_Ring" HorizontalAlignment="Center" Margin="10,10,10,10" VerticalAlignment="Center" Foreground="{StaticResource AndroidGreen}" IsActive="True" Width="40" Height="40"/>
</Grid>
<Grid x:Name="CardViewerGrid_Ring" HorizontalAlignment="Center" Height="416" Margin="0,0,0,0" VerticalAlignment="Center" Width="642"/>
</Grid>
</Border>
Lastly, I'm rendering the user control like this:
//Converting UIelement to Rendered Bitmap
CardViewerGrid_Ring.Children.Add(item); // Adding card to canvas.
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(CardViewerGrid_Ring); // Render canvas.
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
And, voila :)
My problem is that my items won't add to the list. I try to add 3 texts and one image location to the list. I try everything but I couldn't do it.
XAML code
<ListBox Name="mylistbox" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Grid.RowSpan="3">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="s1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="100"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20/"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding naslov}" Tag="{Binding broj}" FontSize="32" Foreground="White" HorizontalAlignment="Center" TextWrapping="Wrap" Grid.Row="1" Grid.Column="2" />
<TextBlock Text="{Binding datum}" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Center" TextWrapping="Wrap" Grid.Row="2" Grid.Column="2"/>
<Image Source="{Binding slika}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
C# code
for (int i = 1; i < datum.Count; ++i)
{
podatak _podatak = new podatak();
_podatak.naslov = naslovi[i];
_podatak.datum = datum[i];
_podatak.broj = Convert.ToString(broj);
_podatak.slika = "http://hsin.hr/images/logo.gif";
mylistbox.Items.Add(_podatak);
}
I didn't test, but I think you are missing one detail, and doing a little mistake.
First: you need to bind a List to a ListBox. So, I believe you should do something like this:
List<podatak> myList = new List<podatak>();
for (int i = 1; i < datum.Count; ++i)
{
podatak _podatak = new podatak();
_podatak.naslov = naslovi[i];
_podatak.datum = datum[i];
_podatak.broj = Convert.ToString(broj);
_podatak.slika = "http://hsin.hr/images/logo.gif";
myList.Add(_podatak);
}
mylistbox.ItemsSource = myList;
And Second: add this on xaml:
<ListBox Name="mylistbox" ItemsSource="{Binding}" ...
Correcting:
As commented, doesn't need change anything on your XAML code.
My mistake.