I know how I can get screen dimensions from code. But how can I pass those numbers to XAML so that I can draw the screen correctly? I am trying to make a basic grid that has 3 rows. The middle one's height should be same as device screen width. What I have now is:
<Grid BackgroundColor="Black">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="I DONT KNOW WHAT TO PUT HERE :S" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" BackgroundColor="Blue" Margin="10" />
</Grid>
To me this seems like a really basic thing, but I can't find any examples on how to do this.
You can get the device info by Xamarin.Essentials: Device Display Information, create a struct called Constant and define the ScreenWidth and ScreenHeight there.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Get Metrics
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
// Orientation (Landscape, Portrait, Square, Unknown)
var orientation = mainDisplayInfo.Orientation;
// Rotation (0, 90, 180, 270)
var rotation = mainDisplayInfo.Rotation;
// Width (in pixels)
var width = mainDisplayInfo.Width;
// Height (in pixels)
var height = mainDisplayInfo.Height;
// Screen density
var density = mainDisplayInfo.Density;
}
}
public struct Constant
{
public static double ScreenWidth = DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Density;
public static double ScreenHeight = DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density;
}
Use it in xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:App105"
x:Class="App105.MainPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="{Binding Source={x:Static local:Constant.ScreenWidth}}" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Top Left" BackgroundColor="Red" Grid.Row="0" Grid.Column="0" />
<Label Text="Top Right" BackgroundColor="Blue" Grid.Row="0" Grid.Column="1" />
<Label Text="middle Left" BackgroundColor="Green" Grid.Row="1" Grid.Column="0" />
<Label Text="middle Right" BackgroundColor="Yellow" Grid.Row="1" Grid.Column="1" />
<Label Text="Bottom Left" BackgroundColor="Orange" Grid.Row="2" Grid.Column="0" />
<Label Text="Bottom Righ" BackgroundColor="Pink" Grid.Row="2" Grid.Column="1" />
</Grid>
</ContentPage>
Related
I am currently trying to build two separate collection views on the same page in Xamarin. I keep getting the error that content is set more than once and also that I've set the content binding more than once. How do I add different bindings to two separate collection views on the same page?
ConsumerOrders.xaml page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewmodels="clr-namespace:Shared.ViewModel"
mc:Ignorable="d"
x:Class="Shared.consumerOrders">
<ContentPage.BindingContext>
<viewmodels:AddedServicesViewModel />
</ContentPage.BindingContext>
<d:ContentPage.BindingContext>
<viewmodels:PastOrderViewModel />
</d:ContentPage.BindingContext>
<ScrollView>
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Services added" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView ItemsSource="{Binding ViewQuoteStatus}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Past Orderrs" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
</ContentPage>
AddedServicesViewModel.cs :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class AddedServicesViewModel
{
readonly IList<AddedServiceStatus> source;
public ObservableCollection<AddedServiceStatus> ViewAddedServices { get; private set; }
public AddedServicesViewModel()
{
source = new List<AddedServiceStatus>();
CreateAddedServicesCollection();
}
void CreateAddedServicesCollection()
{
source.Add(new AddedServiceStatus
{
BusinessName = "Duck's Duct Cleaning"
});
source.Add(new AddedServiceStatus
{
BusinessName = "Rodney's Home Repair"
});
ViewAddedServices = new ObservableCollection<AddedServiceStatus>(source);
}
}
}
PastOrderViewModel :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class PastOrderViewModel
{
readonly IList<PastOrderStatus> source;
public ObservableCollection<PastOrderStatus> ViewPastOrders { get; private set; }
public PastOrderViewModel()
{
source = new List<PastOrderStatus>();
CreatePastOrderCollection();
}
void CreatePastOrderCollection()
{
source.Add(new PastOrderStatus
{
BusinessName = "Karen's Magnificent Dog Grooming"
});
source.Add(new PastOrderStatus
{
BusinessName = "Harry's In Home Haircuts"
});
source.Add(new PastOrderStatus
{
BusinessName = "Shelly's Floral Arrangements"
});
ViewPastOrders = new ObservableCollection<PastOrderStatus>(source);
}
}
}
You could also bind a ViewModel to each CollectionView separately.
like:
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.BindingContext>
<viewmodels:AddedServicesViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
<CollectionView ItemsSource="{Binding ViewPastOrders}">
<CollectionView.BindingContext>
<viewmodels:PastOrderViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
You can't have two ViewModels binding to a SingleView. (as far a I know)
I see that the DataTemplate in both Collections are the same..... there are many ways to refactor....
You could create two CustomView one with the AddedServicesViewModel and the other with PastOrderViewModel
You can merge the two ViewModels into one, and create a CustomView that it's the collection.
Another thing that I see that It could not work is that you can't have a more than one View Nested in a ScrollView
<ScrollView>
<StackLayout> /* Or any other Layout, Grid, Absolute, Flex etc... */
</StackLayout>
</ScrollView>
Another thing is that a CollectionView with orientation vertical in a ScrollView maybe it won't behave as you expect, since the CollectionView with orientation vertical it has Scroll
Two CollectionViews with orientation vertical in the same View it should have a Height, I would do something like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<CollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </CollectionView>
<CollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </CollectionView>
</Grid>
or if you create a custom view (custom control)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<MyCustomCollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </MyCustomCollectionView>
<MyCustomCollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </MyCustomCollectionView>
</Grid>
I ran the program on both Android and iOS platforms, and you can check that the components on iOS are a little above and I would like to center as they are on Android ie adjust it without affecting Android.
I want to modify Grid values
<Grid RowSpacing="0">
<OnPlatform x:TypeArguments="Thickness">
<On Platform="Android">0,10,0,0</On>
<On Platform="iOS">0,20,0,0</On>
</OnPlatform>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="60" />
<RowDefinition Height="280" />
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Orientation="Horizontal" Margin="30,0,30,0">
<local1:Submenu></local1:Submenu>
</StackLayout>
<Label Grid.Row="1" Text="InĂcio" TextColor="White" FontSize="40" Margin="55,10,0,0"></Label>
<Grid Grid.Row="2" ColumnSpacing="5" RowSpacing="5" HorizontalOptions="Center" VerticalOptions="Center" Margin="48,20,48,0" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- button images -->
<Image x:Name="CmdCalendario" Grid.Row="0" Grid.Column="0" Source="calendarioFiscallivre.png" />
<Image x:Name="CmdContaCorrente" Grid.Row="0" Grid.Column="1" Source="botaocadastrolivre.png" />
<Image x:Name="CmdCadastro" Grid.Row="1" Grid.Column="0" Source="botaocadastrolivre.png" />
<Image x:Name="CmdOutros" Grid.Row="1" Grid.Column="1" Source="botaocadastrolivre.png"/>
<!--<Image x:Name="CmdLiquidacao" Grid.Row="1" Grid.Column="0" Source="botaocadastrolivre.png" />-->
</Grid>
</Grid>
I also tested from the back code and it is not working
switch (Device.RuntimePlatform)
{
case Device.iOS:
grid.RowDefinitions.Add(new RowDefinition { Height = 130 });
grid.RowDefinitions.Add(new RowDefinition { Height = 80 });
grid.RowDefinitions.Add(new RowDefinition { Height = 250 });
break;
case Device.Android:
grid.RowDefinitions.Add(new RowDefinition { Height = 100 });
grid.RowDefinitions.Add(new RowDefinition { Height = 80 });
grid.RowDefinitions.Add(new RowDefinition { Height = 280 });
break;
}
Try to specify the Thickness under Grid.Padding property.Thickness is the type of Padding property.
Solution:
<Grid.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="Android">0,10,0,0</On>
<On Platform="iOS">0,20,0,0</On>
</OnPlatform>
</Grid.Padding>
I need to print some informations, and I have print preview page which contains:
<Grid Name="pageGrid" Width="Auto" Height="Auto" Margin="70">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0" Name="headerGrid" Margin="0,0,0,5" />
<Grid Grid.Column="0" Grid.Row="1" Name="pageSummaryGrid" Margin="0" />
<Grid Grid.Column="0" Grid.Row="2" Name="dataGrid" Margin="0" />
<Grid Grid.Column="0" Grid.Row="3" Name="footerGrid" Margin="0,5,0,0" VerticalAlignment="Bottom" />
</Grid>
The header and footer exists on every page. pageSummaryGrid and dataGrid may be populated. Also I have this code which populate print details:
pageCount = pages.Count;
for (int i = 0; i < pageCount; i++)
{
myPage = new PrintPreviewPage();
header = new PrintPageHeader();
footer = new PrintPageFooter();
CreateHeaderAndFooter(i + 1, pageCount, header, footer);
myPage.SetHeader(header);
myPage.SetTableData(pages[i]);
myPage.SetFooter(footer);
pageList.Add(myPage);
}
Methods:
public void SetTableData(Panel panel)
{
dataGridGrid.Children.Add(panel);
}
public void SetHeader(FrameworkElement header)
{
headerGrid.Children.Add(header);
}
public void SetFooter(FrameworkElement footer)
{
footerGrid.Children.Add(footer);
}
pages is list of StackPanel(represent print details, for example some pictures,list etc.) When some pages[i] is larger than real page height then the footer becomes invisible and print details(list,pictures etc.) is cutted(footer is pushed).
I want that footer is always visible, and if I need to cut just print details. I tried to set MaxHeight, Height, ActualHeight and ClipToBounds properties of StackPanel, but nothing works. Any idea?
I apologize for the length of this post but this one bums me out for two days straight now. Consider the image below. On Mouseclick on one of the tiles 1-4 the tiles resize and a big tile 5 appears in the middle. Another mouseclick reverses the process.
First I tried to bind the width/height property of row- and columndefinitions directly. This didn't work at all. The current solution uses the width and height property of labels to get the resizing done. The code is as follows...
XAML:
....
<Grid Name ="MainGrid" Background="Crimson">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid Name="LeftGrid" Grid.Column ="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1"/>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Column ="1" Grid.Row ="0" Background ="Cyan " Width="200" Name="HandleLeftTop" />
<Label Grid.Column ="0" Grid.Row ="1" Background ="Cyan " Width="200" Name="HandleLeftSideTop" />
<Label Grid.Column ="0" Grid.Row ="2" Background ="Cyan " Width="200" Name="HandleLeftSideBottom"/>
<Grid Grid.Column ="1" Grid.Row ="1" Background ="Green" MouseDown="Grid_MouseDown"> </Grid>
<Grid Grid.Column ="1" Grid.Row ="2" Background ="Yellow" MouseDown="Grid_MouseDown_1"></Grid>
</Grid>
<Grid Name="RightGrid" Grid.Column ="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1"/>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Column ="0" Grid.Row ="0" Background ="Cyan " Width="200" Name="HandleRightTop"/>
<Label Grid.Column ="1" Grid.Row ="1" Background ="Cyan " Width="200" Name="HandleRightSideTop"/>
<Label Grid.Column ="1" Grid.Row ="2" Background ="Cyan " Width="200" Name="HandleRightSideBottom"/>
<Grid Grid.Column ="0" Grid.Row ="1" Background ="Thistle " MouseDown="Grid_MouseDown_2"></Grid>
<Grid Grid.Column ="0" Grid.Row ="2" Background ="Tan " MouseDown="Grid_MouseDown_3"></Grid>
</Grid>
<Grid Name="MiddleGrid" Grid.Column ="1">
<Grid.RowDefinitions>
<RowDefinition Height="1"/>
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row ="0" Background ="Cyan " Width="200" Name="HandleMiddleTop" />
<Grid Grid.Column ="0" Grid.Row ="1" Background ="Tomato"/>
</Grid>
</Grid>
C#:
public partial class RTGraphControl : UserControl
{
private readonly RTGraphControlViewModel _viewModel;
public RTGraphControl()
{
InitializeComponent();
_viewModel = new RTGraphControlViewModel(this);
DataContext = _viewModel;
//.... Binding row heights etc...
var leftColumnWidthbindingElement = new Binding
{
Source = _viewModel,
Path = new PropertyPath("LeftColumnWidth"),
Mode = BindingMode.OneWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
HandleLeftTop.SetBinding(WidthProperty, leftColumnWidthbindingElement);
// same for right and middle column
_viewModel.Expanded = false;
}
}
public class RTGraphControlViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private readonly RTGraphControl _rt;
private bool _expanded;
private double _rowHeight;
private double _leftcolumnWidth;
private double _middlecolumnWidth;
private double _rightcolumnWidth;
public RTGraphControlViewModel(RTGraphControl rt)
{
_rt = rt;
}
public bool Expanded
{
get { return _expanded; }
set
{
_expanded = value;
double width = _rt.MainGrid.ActualWidth;
if (_expanded)
{
LeftColumnWidth = width*0.2;
RightColumnwidth = width*0.2;
MiddleColumnWidth = width*0.6;
}
else
{
LeftColumnWidth = width * 0.5;
RightColumnwidth = width * 0.5;
MiddleColumnWidth = width * 0;
}
OnPropertyChanged("Expanded");
}
}
public double LeftColumnWidth
{
get { return _leftcolumnWidth; }
set
{
_leftcolumnWidth = value;
OnPropertyChanged("LeftColumnWidth");
}
}
public double MiddleColumnWidth {...}
public double RightColumnwidth {...}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
This kind of works for the left and middle column but funnily enough it doesn't for the right column. The right column doesn't change its width at all. Another problem is that after initialization of the usercontrol actualwidth is set to 0. A workaround with .Measure and .Arrange didn't work.
Thanks in advance
Jon
You could define your XAML like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0" Background="ForestGreen" Margin="2"
MouseDown="OuterContainer_OnMouseDown" />
<Grid Grid.Column="2" Grid.Row="0" Background="LimeGreen" Margin="2"
MouseDown="OuterContainer_OnMouseDown" />
<Grid Grid.Column="0" Grid.Row="1" Background="Firebrick" Margin="2"
MouseDown="OuterContainer_OnMouseDown" />
<Grid Grid.Column="2" Grid.Row="1" Background="OrangeRed" Margin="2"
MouseDown="OuterContainer_OnMouseDown" />
<Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Background="DodgerBlue"
MouseDown="MiddleContainer_OnMouseDown" x:Name="MiddleContainer"
Visibility="Collapsed" Width="300" Margin="2" />
</Grid>
Then a little code-behind to show/hide the middle box:
private void OuterContainer_OnMouseDown(object sender, MouseButtonEventArgs e)
{
MiddleContainer.Visibility = Visibility.Visible;
}
private void MiddleContainer_OnMouseDown(object sender, MouseButtonEventArgs e)
{
MiddleContainer.Visibility = Visibility.Collapsed;
}
Hidden:
Showing:
The only caveat is that the middle box has a preset size (300, but you can change that), instead of 60%. Not sure what you're intending to do with it, so that may or may not be an issue.
Now, I create a Canvas as my 2D RPG's Map . Indeed, I create a array cells[6*6].
int x=6;
int y=6 ;
bool[,] cells = new bool[x,y];
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
cells[i, j] = true;
}
}
And then
<Window x:Class="ASTHENIA.GameIng"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ASTHENIA" Height="650" Width="800" ResizeMode="NoResize" Closed="Window_Closed_1" WindowStartupLocation="CenterScreen">
<Grid Name="MyGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.05*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0.05*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0.05*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.02*" />
<RowDefinition Height="0.3*" />
<RowDefinition Height="*" />
<RowDefinition Height="0.3*" />
<RowDefinition Height="0.02*" />
</Grid.RowDefinitions>
<Button Grid.Column="5" Grid.Row="3" Width="100" Height="80" Click="Button_Click_1" >
<Button.Background>
<ImageBrush ImageSource="Resources/back.png"/>
</Button.Background>
</Button>
<TextBlock Grid.Column="5" Grid.Row="1" Grid.RowSpan="2" />
<Canvas Name="Map" Grid.Row ="2" Grid.Column="1" Grid.ColumnSpan="3" Grid.RowSpan="1" >
</Canvas>
</Grid>
</Window>
How to decompose the Canvas to 6*6. And the first left of cells is cell[0,0].
Do you really need a canvas?
A canvas is a raw uniform surface, and you want a matrix-like surface.
So you'd rather use a UniformGrid with elements being small canvas.
Or you can write you're own matrix-like surface control...