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...
Related
Goal: When I enter a value in the textbox for Technician Name: I want it to update inside the DataModel and when I click to the NewCallView it will display inside the newcall View and when I click back to the DefaultViewModel it will appear still entered.
Problem: When i change between views the data resets.
I am going to provide my full code in an effort to figure out why my data keeps resetting. - I am still learning MVVM this is my first crack at it. I would normally make a 1 page application using code-behind. I am finding it hard to link up my Model to my ViewModels, and maybe I am calling (getting/setting) the properties incorrectly.
With regards to the code behind for each of my Views I did not alter it at all from its creation, I only worked in the Xaml.
Mainwindow codebehind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using callFlow.ViewModels;
using callFlow.Models;
namespace callFlow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void DefaultViewClicked(object sender, RoutedEventArgs e)
{
DataContext = new DefaultViewModel();
}
private void NewCallClicked(object sender, RoutedEventArgs e)
{
DataContext = new NewCallViewModel();
}
}
}
Main Window View / wpf
<Window x:Class="callFlow.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:callFlow"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
xmlns:views="clr-namespace:callFlow.Views"
mc:Ignorable="d"
Title="Call FLow Management" Height="728" Width="1260">
<Window.Resources>
<DataTemplate x:Name="defaultViewTemplate" DataType="{x:Type viewmodels:DefaultViewModel}">
<views:DefaultView DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate x:Name="newCallViewTemplate" DataType="{x:Type viewmodels:NewCallViewModel}">
<views:NewCallView DataContext="{Binding}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Grid.RowSpan="6" Background="
{DynamicResource {x:Static SystemColors.MenuBrushKey}}"/>
<Grid Grid.Row="1" Grid.Column="0" Grid.RowSpan="6" />
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Background="FloralWhite">
<Image Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Source="/BofA2.png" Width="400"
HorizontalAlignment="Left" />
<Border BorderThickness="1" BorderBrush="Black" Grid.Column="0" Grid.Row="0"
Grid.ColumnSpan="6" CornerRadius="8 8 8 8"/>
<Border BorderThickness="1" BorderBrush="Black" Grid.Column="0" Grid.Row="1"
Grid.RowSpan="6"
CornerRadius="8 8 8 8"/>
</Grid>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.RowSpan="6">
<Button Name="loadDefaultView" Content="Home" Grid.Column="2" Grid.Row="2" Height="40"
Margin="5 5 5 5" Click="DefaultViewClicked" > </Button>
<Button Name="loadNewCall" Content="New Call" Grid.Column="2" Grid.Row="2" Height="40"
Margin="5 0 5 0 " Click="NewCallClicked" ></Button>
</StackPanel>
<ContentControl Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="6" Content="
{Binding}">
</ContentControl>
</Grid>
</Window>
Views/DefaultView.xaml
<UserControl x:Class="callFlow.Views.DefaultView"
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:callFlow.Views"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
xmlns:model="clr-namespace:callFlow.Models"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="FloralWhite">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="7" Margin="0 10 0 0" HorizontalAlignment="Center"
Text="Call Flow Management" TextWrapping="Wrap" FontSize="24" VerticalAlignment="Top"/>
<StackPanel Grid.Row="0" Grid.Column="5" Grid.ColumnSpan="1" Margin="0 5 0 0">
<TextBlock HorizontalAlignment="Left" Grid.Column="0" Grid.Row="1" Text="Technician Name: "
FontSize="14" TextWrapping="Wrap" Grid.ColumnSpan="2" Width="134"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="6" Grid.ColumnSpan="1" Margin="5 5 5 0">
<TextBox Name="techName" Text="{Binding SelectedModel.TechName,Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF4A5780" Grid.RowSpan="2" />
</StackPanel>
<TextBlock x:Name="TextUpdate" Grid.Column="5" HorizontalAlignment="Left" Margin="41,0,0,0"
Grid.Row="1" Text="{Binding SelectedModel.TechName}" TextWrapping="Wrap" VerticalAlignment="Center"/>
</Grid>
</UserControl>
ViewModels/DefaultViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using callFlow.Models;
namespace callFlow.ViewModels
{
public class DefaultViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public DefaultViewModel() { }
private ObservableCollection<DataModel> model = new ObservableCollection<DataModel>();
private DataModel _SelectedModel;
public DataModel SelectedModel
{
get { return _SelectedModel ?? (_SelectedModel = new DataModel()); }
set { _SelectedModel = value; OnPropertyChanged(); }
}
public void changeSelectedModel(DataModel newSelectedModel)
{
SelectedModel.TechName = newSelectedModel.TechName;
}
private void OnPropertyChanged([CallerMemberName] string techName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(techName));
}
}
}
Views\NewCallView.xaml
<UserControl x:Class="callFlow.Views.NewCallView"
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:callFlow.Views"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="#FFFDFDFD">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="techNameSet" Grid.Column="2" HorizontalAlignment="Left" Margin="40,52,0,0"
Grid.Row="2" Text="{Binding SelectedModel.TechName}" TextWrapping="Wrap" VerticalAlignment="Top"
Grid.ColumnSpan="2" Width="114"/>
</Grid>
</UserControl>
NewCallViewModel.cs
namespace callFlow.ViewModels
{
class NewCallViewModel
{
//It's empty, my view is calling SelectedModel.TechName from DataViewModel which works when I update the DataModel Directly
}
}
Last but not least!!!!
Models/DataModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Drawing;
namespace callFlow.Models
{
public class DataModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string techName;
public DataModel()
{
}
public string TechName
{
get { return techName; }
set { techName = value; OnPropertyChanged(); }
}
private void OnPropertyChanged([CallerMemberName] string techName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(techName));
}
}
}
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>
I asked a few months ago similarly question, but now I have different problem and I am not sure how to solve that.
Picture below describes what I want to implement - in fact I want DataGrid behavior. With 'fixed' keyword I mean that:
1) Header is always visible when I use vertical scrollbar, and header is moving if I use horizontal scrollbar
2) Rows are always visible when I use horizontal scrollbar, and rows are moving if I use vertical scrollbar
I need to create Grid on dynamically way, because I don't know number of rows or columns in advance.
My current solution doesn't include 'fixed rows' and my vertical scroll bar is not visible always (orange line at picture).
XAML
<Grid>
<Grid Grid.IsSharedSizeScope="True">
<ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Grid.Row="2" Grid.ColumnSpan="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="600" />
</Grid.RowDefinitions>
<Grid x:Name="HeaderDaysGrid" Margin="10,0,0,0" Grid.Row="0" ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" MaxWidth="150"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
<ColumnDefinition Width="*" MaxWidth="240"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
</Grid>
<Grid x:Name="SchedulerGridWrapper" Grid.Row="1" Margin="10,0,0,5">
<ScrollViewer x:Name="SchedulerScrolViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Height="600">
<Grid x:Name="WeekSchedulerGrid" ShowCustomGridLines="False" ScrollViewer.CanContentScroll="True" />
</ScrollViewer>
</Grid>
</Grid>
</ScrollViewer>
</Grid>
</Grid>
And in code behind I have something like this:
private void CreateWeekGrid()
{
WeekSchedulerGrid.Children.Clear();
WeekSchedulerGrid.RowDefinitions.Clear();
WeekSchedulerGrid.ColumnDefinitions.Clear();
HeaderDaysGrid.Children.Clear();
CreateColumnDefinition(WeekSchedulerGrid, NUMBER_OF_COLUMNS, GRID_COLUMN_WIDTH);
CreateRowDefinition(ref WeekSchedulerGrid, _numberOfRows);
for(int row = 0; row < _numberOfRows; row++)
{
TextBlock textBlock = new TextBlock { Text = "Some row name"};
Grid.SetRow(textBlock, row);
Grid.SetColumn(textBlock, 0);
WeekSchedulerGrid.Children.Add(textBlock);
}
foreach (var item in _headerList)
{
HeaderDaysGrid.Children.Add(item);
}
}
private void CreateRowDefinition(ref SchedulerGrid grid, int numberOfRows)
{
for (int row = 0; row < numberOfRows; row++)
{
RowDefinition gridRow = new RowDefinition();
gridRow.MinHeight = 100;
gridRow.MaxHeight = 300;
grid.RowDefinitions.Add(gridRow);
}
}
private void CreateColumnDefinition(ref SchedulerGrid grid, int numberOfColumns, int columnWidth)
{
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
ColumnDefinition gridCol = new ColumnDefinition();
grid.ColumnDefinitions.Add(gridCol);
if (colIndex == 0)
{
gridCol.Width = new GridLength(1, GridUnitType.Star);
gridCol.MaxWidth = 150;
}
else
{
gridCol.Width = columnWidth;
}
}
}
With this solution I am not sure how to implement 'fixed rows' and to have functionalities described on the picture. Code behind, XAML and binding or something else?
I probably can't join 'fixed rows' and all cells in one grid - because of scroll bar. 'Fixed rows', 'fixed header' and 'all cells' needs to be separate grid? But how to create such a layout and desired behavior? I'm really not sure.
In addition, this custom grid is used like scheduler and shows some custom events(user controls) in his cells, so I probably can't use DataGrid. And sorry for bad English.
I resolved the problem on next way. I have three grids. If you look at the image 'Fixed header', 'Fixed rows' and 'Gray surface for content' are separate grids now.
Also I have three scroll viewers. Only the scroll viewer for content is visible. Other scroll viewers are set as hidden, but I update theirs values in code behind when content scroll viewer position is changed.
XAML
<Grid">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="HeaderDaysScrolViewer" CanContentScroll="True" Grid.Row="0" Grid.Column="1" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<Grid x:Name="HeaderDaysGrid" Margin="10,0,0,0" ShowGridLines="False"/>
</ScrollViewer>
<ScrollViewer x:Name="VerticalScrolViewer" CanContentScroll="True" Grid.Row="1" Grid.Column="0"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<Grid x:Name="VerticalDataGrid" ShowCustomGridLines="True" GridLineThickness="0.5" GridLineBrush="#FF434343"/>
</ScrollViewer>
<ScrollViewer x:Name="SchedulerScrolViewer" HorizontalScrollBarVisibility="Visible" VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Visible" ScrollChanged="SchedulerScrolViewer_ScrollChanged" Grid.Row="1" Grid.Column="1" Margin="10,0,0,5">
<Grid>
<Grid x:Name="WeekSchedulerGrid" ShowCustomGridLines="False" ScrollViewer.CanContentScroll="True"/>
</Grid>
</ScrollViewer>
</Grid>
Code behind
private void SchedulerScrolViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
HeaderDaysScrolViewer.ScrollToHorizontalOffset(e.HorizontalOffset);
OverviewTypesScrolViewer.ScrollToVerticalOffset(e.VerticalOffset);
}
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="HeaderDays" Height="35"/>
<RowDefinition x:Name="ScrollAreaRows" Height="600"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="HeaderRows" Width="35"/>
<ColumnDefinition x:Name="ScrollAreaColumns" Width="600"/>
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="DataScroller" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible" Grid.Row="1" Grid.Column="1">
<Grid x:Name="DataGrid" Height="{Binding Height, ElementName=ScrollAreaRows, UpdateSourceTrigger=PropertyChanged}" Widht="{Binding Width, ElementName=ScrollAreaColumns, UpdateSourceTrigger=PropertyChanged}">
</ScrollViewer>
the grid named "DataGrid" is the one that should scroll horizontally and vertically, while letting row0 and column0 of the outside grid to visually "stay static".
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...).
I'm trying to postion views to the window in layout which is rectangle base while using MVVM pattern.
In WinForms I was able to use width, height, x and y of rectagle to position controls easily by just setting same properties on control.
Now I'm rewriting this code to wpf using MVVM and I'm lost.
this is what I'm trying to do:
This is something I thought might work but it does not.
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding VirtualScreens}" Grid.IsSharedSizeScope="True" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Grid.Row="{Binding Row}" Grid.Column="{Binding Column}" Content="{Binding Name}"></Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
public class VirtualScreen : ObservableObject
{
string name;
int row;
int column;
public string Name
{
get { return name; }
set
{
name = value;
RaisePropertyChanged(() => Name);
}
}
public int Row
{
get { return row; }
set
{
row = value;
RaisePropertyChanged(() => Row);
}
}
public int Column
{
get { return column; }
set
{
this.column = value;
RaisePropertyChanged(() => Column);
}
}
}
Thank you for any type of help
you could use ItemsControl ItemsPanel, ItemsTemplate and ItemContainerStyle.
Here is an example for you
<ItemsControl ItemsSource="{Binding VirtualScreens}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Style.Setters>
<Setter Property="Grid.Row" Value="{Binding Row}" />
<Setter Property="Grid.Column" Value="{Binding Column}" />
</Style.Setters>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
You can use a WPF Grid to layout the elements as shown in your UI. A three-row, three-column grid would work fine for you:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Grid.RowSpan="2">This is the big top left section</Button>
<Button Grid.Row="1" Grid.Column="2">Top right</Button>
<Button Grid.Row="2" Grid.Column="2">Middle right</Button>
<Button Grid.Row="3" Grid.Column="1">Bottom left</Button>
<Button Grid.Row="3" Grid.Column="2">Bottom center</Button>
<Button Grid.Row="3" Grid.Column="2">Bottom right</Button>
</Grid>
Checkout Grid Row and Column Spanning for more info.