how to create listview to a grid programmatically - c#

I have a grid with columns and rows define. By knowing x amount of items, I can add it to my xaml no problem. Unfortuantely I want to create the listview programatically because I want to populate them based on x amount of item I get when executing my SP. Here is my xaml. The label is there to assign a given content from the SP result too. Can someone show me how create this programatically?
<Grid Name="grdItems" Width="939" Grid.Row="1" HorizontalAlignment="Left" DataContext="{Binding}" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="231"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="231"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="231"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="231"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Name="lblItem" Grid.Row="0" Grid.Column="0" Content="item label" />
<ListView Name="lstFirstItem" HorizontalAlignment="Left" VerticalAlignment="Top"
Height="auto" Margin="0,0,0,0" ItemsSource="" FontWeight="Regular"
Grid.Column="0" Grid.Row="1">
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style>
<Setter Property="FrameworkElement.Visibility" Value="Collapsed"/>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn Width="58" DisplayMemberBinding="{Binding ItemName}"></GridViewColumn>
<GridViewColumn Width="174.25" DisplayMemberBinding="{Binding ItemDescription}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>

we can add rows or columns dynamically from code behind.
Inorder to add rows:
GridLength rowheight = new GridLength(100); //your own value we can give *,Auto as well
RowDefinition rowDef = new RowDefinition {Height = rowheight };
mainGrid.RowDefinitions.Add(rowDef);
Inorder to add colomns:
GridLength columnwidth = new GridLength(100);
ColumnDefinition colDef = new ColumnDefinition { Width = columnwidth};
mainGrid.ColumnDefinitions.Add(colDef );
Inorder to add textblock at particular row,column
TextBlock textBlock = new TextBlock();
textBlock.Text = "Some Value";
Grid.SetRow(textBlock, rowNum);
Grid.SetColumn(textBlock, colNum);
mainGrid.Children.Add(textBlock);
Hope this answers your question

This work perfectly for me:
ListView Lv_Report = new ListView();
Lv_Report.Name = "Lv_Report";
Lv_Report.FontSize = 14;
Lv_Report.Height = 300;
Lv_Report.Width = 800;
Canvas.SetTop(Lv_Report, 10);
Canvas.SetLeft(Lv_Report, 30);
Cv_Scheduler.Children.Add(Lv_Report);
Lv_Report.Background = null;
LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush();
myLinearGradientBrush.StartPoint = new System.Windows.Point(0, 0);
myLinearGradientBrush.EndPoint = new System.Windows.Point(0, 1);
Color color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#7FFFFFFF");
myLinearGradientBrush.GradientStops.Add(new GradientStop(color, 0.02));
color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#BFBADF69");
myLinearGradientBrush.GradientStops.Add(new GradientStop(color, 0.19));
color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#7FF9FCF2");
myLinearGradientBrush.GradientStops.Add(new GradientStop(color, 1));
color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#BEB9DE67");
myLinearGradientBrush.GradientStops.Add(new GradientStop(color, 0.83));
Style style = new Style(typeof(GridViewColumnHeader));
style.Setters.Add(new Setter()
{
Property = GridViewColumnHeader.BackgroundProperty,
Value = myLinearGradientBrush
});
var Lvitems = new List<string>();
Lvitems.Add("WorkOrder");
Lvitems.Add("Module1");
GridView Gv = new GridView();
foreach (String item in Lvitems)
{
DataTemplate Dtemplate = new DataTemplate();
var markup =
"<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:local=\"clr-namespace:SubMeteringElectric;assembly=SubMeteringElectric\">"
+ "<StackPanel>"
+ "<Label Content =\"{Binding Lv_RSH_" + item + "}\" Width = \"100\" Height = \"30\" HorizontalContentAlignment = \"Center\" FontSize = \"14\" />"
+ "</StackPanel>"
+ "</DataTemplate>";
byte[] byteArray = Encoding.UTF8.GetBytes(markup);
MemoryStream stream = new MemoryStream(byteArray);
Dtemplate = (DataTemplate)XamlReader.Load(stream);
GridViewColumn Gvc_item = new GridViewColumn();
Gvc_item.Header = item;
Gvc_item.Width = 150;
Gvc_item.CellTemplate = Dtemplate;
Gv.Columns.Add(Gvc_item);
}
Gv.ColumnHeaderContainerStyle = style;
Lv_Report.View = Gv;
}

Related

Width of a grid column

I have a problem with setting a Column width in my grid. That grid is auto-generated inside a button and I don't know the actual width of it nor the width of a window. I have defined two columns in it, one has static width and for the second one I want to be set to all the left place. Problem is that I am generating all those grids and columns just at the moment of running of a program so I'm not able to use the width property of any other object as everything is double.NaN.
What I want to do is generating a button grid containing two columns, one static width and the second which width can change through the time like on the picture (the red text is just a comment).
The code I use for generating that grid. The problematic column is the one with width property set to "???" for now:
Button GridButton = new Button()
{
HorizontalAlignment = HorizontalAlignment.Stretch,
Margin = new Thickness { Left = 10, Right = 5, Top = 10, Bottom = 10 },
Height = 70,
/*HorizontalAlignment = HorizontalAlignment.Center,
HorizontalContentAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Top,
VerticalContentAlignment = VerticalAlignment.Center,
*/
Tag = GridButtonTag,
Background = new SolidColorBrush(Colors.White),
Padding = new Thickness { Left = 0, Right = 0, Bottom = 0, Top = 0 }
};
WholeGrid.Children.Add(GridButton);
Grid ButtonContentGrid = new Grid()
{
Padding = new Thickness { Left = 0, Right = 0, Top = 0, Bottom = 0 },
};
double ColumnWidth = GridButton.Width - 80;
ColumnDefinition Column1 = new ColumnDefinition();
ColumnDefinition Column2 = new ColumnDefinition();
Column1.Width = new GridLength(????);
Column2.Width = new GridLength(90);
ButtonContentGrid.ColumnDefinitions.Add(Column1);
ButtonContentGrid.ColumnDefinitions.Add(Column2);
TextBlock Questions = new TextBlock()
{
Margin = new Thickness { Right = 0, Top = 0, Bottom = 0 },
Width = 90,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Right,
FontSize = 45,
Text = QuestionsAmount,
FontWeight = FontWeights.Bold,
TextAlignment = TextAlignment.Right
};
Grid QuestionsGrid = new Grid()
{
Width = 90,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center
};
QuestionsGrid.Children.Add(Questions);
Grid.SetColumn(QuestionsGrid, 1);
ButtonContentGrid.Children.Add(QuestionsGrid);
Grid TwoTexts = new Grid()
{
Height = 70,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Stretch,
Width = GridButton.Width - 80,
Padding = new Thickness { Left = 0, Right = 0, Top = 0, Bottom = 0 }
};
RowDefinition TextRow1 = new RowDefinition();
RowDefinition TextRow2 = new RowDefinition();
TextRow1.Height = new GridLength(50);
TextRow2.Height = new GridLength(20);
TwoTexts.RowDefinitions.Add(TextRow1);
TwoTexts.RowDefinitions.Add(TextRow2);
TextBlock NameBox = new TextBlock()
{
Margin = new Thickness { Left = 0, Top = 0},
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Left,
FontSize = 35,
Text = Name,
FontWeight = FontWeights.Bold
};
TextBlock DescriptionBox = new TextBlock()
{
Margin = new Thickness { Left = 0, Bottom = -10 },
VerticalAlignment = VerticalAlignment.Bottom,
HorizontalAlignment = HorizontalAlignment.Left,
FontSize = 15,
Text = Description
};
Grid.SetRow(NameBox, 0);
TwoTexts.Children.Add(NameBox);
Grid.SetColumn(DescriptionBox, 1);
TwoTexts.Children.Add(DescriptionBox);
Grid.SetColumn(TwoTexts, 0);
ButtonContentGrid.Children.Add(TwoTexts);
GridButton.Content = ButtonContentGrid;
Alternate option - ListView (still the same problem and again the Place With WidthValue="????" is the one I don't know how to set):
<ListView Name="FileListView" Margin="0,0,0,0" Padding="10,10,10,10">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="90" Margin="0,0,0,0" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="2"/>
<RowDefinition Height="92"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
BorderThickness="0,2"
CornerRadius="2"
BorderBrush="Black"
Margin="40,0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
/>
<Grid Grid.Row="1" Height="90" Margin="0" Padding="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="65"/>
</Grid.ColumnDefinitions>
<Grid Name ="Texts" Grid.Column="0" HorizontalAlignment="Stretch" Margin="10,10">
<Button HorizontalAlignment ="Stretch" Margin ="0" Height = "70" Tag = "{Binding GridButtonTag}" Background ="#00FFFFFF" Padding = "0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="90"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" FontSize = "45" FontWeight="Bold" TextAlignment="Right" Text="{Binding QuestionsAmount}" />
<Grid Grid.Column="0" Width="????">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize = "35" FontWeight="Bold" TextAlignment="Left" Text="{Binding Name}" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" FontSize = "17" TextAlignment="Left" Text="{Binding Description}" VerticalAlignment="Center"/>
</Grid>
</Grid>
</Button>
</Grid>
<Grid Grid.Column="1">
<Grid Name="Buttons" Width ="65" HorizontalAlignment="Stretch" Padding = "10,5,10,10" Height = "90" Margin = "0">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Tag = "{Binding PlayButtonTag}" Margin = "0" Height = "50" Width = "50" HorizontalAlignment = "Center" HorizontalContentAlignment = "Center" VerticalAlignment = "Top" VerticalContentAlignment = "Center" Background = "#00FFFFFF" Padding = "0">
<Image Width="50" Height="50" Source="ms-appx:///Assets/Images/PlayIcon.png" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
<Grid Grid.Row="1" Margin="0,0,0,0" Padding="0,0,0,0" Width="50" Height="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Tag = "{Binding EditButtonTag}" Margin = "0" Height = "20" Width = "20" HorizontalAlignment = "Left" HorizontalContentAlignment = "Center" VerticalAlignment = "Top" VerticalContentAlignment = "Center" Background = "#00FFFFFF" Padding = "0">
<Image Width="20" Height="20" Source="ms-appx:///Assets/Images/EditIcon.png" HorizontalAlignment="Center" VerticalAlignment="Center"
</Button>
<Button Grid.Column="1" Margin = "0" Tag = "{Binding DeleteButtonTag}" Height = "20" Width = "20" HorizontalAlignment = "Right" HorizontalContentAlignment = "Center" VerticalAlignment = "Top" VerticalContentAlignment = "Center" Background = "#00FFFFFF" Padding = "0">
<Image Width="20" Height="20" Source="ms-appx:///Assets/Images/DeleteIcon.png" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The question is what should I change or write in that code to achieve the right result?
Thanks in advance.
I don't think you have to set the Width you're trying to set. The problem in this case should be that the content of the DataTemplate is not stretched at all.
You have to add the following lines to your ListView to let the content stretch:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
By the way, I see, you are using Grid with ColumnDefinitions or RowDefinitions really often in your ListView. This could slow down your UI.. You should consider using StackPanel and RelativePanel as well as removing some unnecessary Grids.

How To Create a Grid inside a Listview Binding Xamarin.Forms

How can I create a Grid inside a ListView with data binding? I am creating this app with Xamarin.Forms.
If I don't know how many rows and columns I need, how can I dynamically create the Grid inside the ListView binding?
This is what I have so far:
<ListView x:Name="List" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid Padding="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="200"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackLayout BackgroundColor="#313FA0" Grid.Row="0" Grid.Column="0" HeightRequest="200" WidthRequest="200">
<Label Text="{Binding NUMBER}" FontSize="50" TextColor="White" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding NAME}" FontSize="30" TextColor="White" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</StackLayout>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In this code only one row and one column are created. If I have multiple data points, how can I resolve this issue? For example, if I need one row with two columns.
You can use the next approach-example (throug xaml, front side) as well.
<ContentPage.Resources>
<ResourceDictionary>
<Color x:FactoryMethod="FromHex" x:Key="fondoBlancoPalido">
<x:Arguments>
<x:String>#F2F2F2</x:String>
</x:Arguments>
</Color>
</ResourceDictionary>
</ContentPage.Resources>
<ListView x:Name="listView" HasUnevenRows="True" ItemsSource="{Binding .}" BackgroundColor="{StaticResource fondoBlancoPalido}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="10"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Clicked="OnStartClicked" Image="play.png" BackgroundColor="Transparent" HorizontalOptions="Center" Grid.RowSpan="2"/>
<Label Grid.Row="0" Grid.Column="1" Text="Hora de Inicio: " XAlign="Center" YAlign="Center" TextColor="Black" FontAttributes="Bold"/>
<Label Grid.Row="0" Grid.Column="2" Text="{ Binding attribute3 }" XAlign="Center" YAlign="Center" TextColor="Black"/>
<Label Grid.Row="1" Grid.Column="1" Text="Encargado de la Tarea: " XAlign="Center" YAlign="Center" TextColor="Black" FontAttributes="Bold"/>
<Label Grid.Row="1" Grid.Column="2" Text="{ Binding attribute4 }" XAlign="Center" YAlign="Center" TextColor="Black"/>
<BoxView Color="Navy" HeightRequest="2" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"/>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
There is not a good way to dynamically build a Grid layout with a variable number of rows or columns in XAML. I suggest creating the DataTemplate in your code-behind file, where you can easily add as many RowDefinitions and ColumnDefinitions as you need. Here's an example:
var myDataTemplate = new DataTemplate(() =>
{
var cell = new ViewCell();
var grid = new Grid();
foreach (var record in myRecords)
{
grid.RowDefinitions.Add(new RowDefinition());
}
foreach (var field in myFields)
{
grid.ColumnDefinitions.Add(new ColumnDefinition());
}
/*
*
* Populate grid here...
*
*/
cell.View = grid;
return cell;
});
Then just assign this DataTemplate to your ListView.
If you want to add rows and column dynamically you can create a grid in the page.cs and bind it in the page.xaml. Suppose you have array of items and you want to sort them in grid :
public page()
{
string[] items = {"Item 1","Item 2",......."Item n"};
var itemsGrid = new Grid();
int k = 1 + items.Length / 3;
// just to make it clear in the for loop i used (int k)
// suppose 3 column need we divide on 3
// define the number of rows according to the number of item you have
for (int i = 0; i <k ; i++)
{
itemsGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
}
// defining column number (in this case 3)
for (int j = 0; j < 3; j++)
{
itemsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
}
// adding the items to the grid (3 column , RN rows)
int RN = 0; // initializing the row number
for (int num = 0; num < items.Length; num++)
{
if (num % 3 == 0) // first column
{
itemsGrid.Children.Add(new Label() // adding the item as label
{
Text = items[num],
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center
}, 0, RN);
}
else if (num % 3 == 1)// second column
{
itemsGrid.Children.Add(new Label()
{
Text = items[num],
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center
}, 1, RN);
}
else //third column
{
itemsGrid.Children.Add(new Label()
{
Text = items[num],
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center
}, 2, RN);
RN++;
}
}
}

Windows Phone - Customizing GridView Max Columns

I'm new to Windows Phone programming. I want to create a gridview like the following:
I've done the <DataTemplate>, so I've already done the items and their buttons. But I can't set 2 columns for the grid using MaximumRowsOrColumns, because it limits my grid with only 2 rows (can be ilimited rows, but I need to have only 2 columns).
Coding as below was the closest I made:
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical" MaximumRowsOrColumns="2"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
EDIT: added <DataTemplate>code:
<DataTemplate x:Key="gridClassItem">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="14.96"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="14.96" />
</Grid.ColumnDefinitions>
<Button x:Name="btnItem" Grid.Row="0" Grid.Column="0"
BorderThickness="0 0 0 2" Opacity="100"
Height="70.4" Width="174.24"
Background="#FF6B33"
Click="btnItem_OnClick">
<TextBlock x:Name="txtItem" FontSize="38" Foreground="#5B1F08" Opacity="100" Margin="0" Text="{Binding Name}" TextAlignment="Center"/>
</Button>
<Grid Grid.Row="1" Grid.Column="0" Margin="0, -8, 0, 0" Height="52.8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="86.24"/>
<ColumnDefinition Width="86.24"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn1" Click="btn1_OnClick"
Grid.Row="0" Grid.Column="0"
BorderBrush="#FFFFFF" BorderThickness="0 0 1.76 0"
Margin="-10, -15, 0, 0"
DataContext="{Binding}">
<Button.Background>
<ImageBrush ImageSource="\Assets\bt1.png" Stretch="UniformToFill"/>
</Button.Background>
</Button>
<Button x:Name="btn2" Click="btn2_OnClick"
Grid.Row="0" Grid.Column="1"
BorderBrush="#FFFFFF" BorderThickness="1.76 0 0 0"
Margin="0, -15, -2.5, 0"
DataContext="{Binding}">
<Button.Background>
<ImageBrush ImageSource="\Assets\bt2.png" Stretch="UniformToFill"/>
</Button.Background>
</Button>
</Grid>
<Rectangle Grid.Row="2" Grid.Column="1" Fill="#FFFFFF" Margin="0"/>
</Grid>
</DataTemplate>
Any suggestions?
By the way, any idea how could i change the GridViewItem's background color? I was thinking about a geometric series, like the first item will be orange, the followings - always counting by two - will be green and then orange again. But I don't know how to implement it.
Well, since I couldn't find a way to do it using XAML, I did it at C#. Below is my solution, if someone need something looked like:
enum GridItemColor
{
NONE,
BLUE,
RED
};
//Some event to populate a list
...
myGrid.Items.Clear();
GridItemColor lastColor = GridItemColor.NONE;
foreach (MyModel item in myList)
{
if (lastColor == GridItemColor.NONE || lastColor == GridItemColor.BLUE)
{
myGrid.Items.Add(FormatGridViewItem(item, GridItemColor.RED));
lastColor = GridItemColor.RED;
}
else if (lastColor == GridItemColor.RED)
{
myGrid.Items.Add(FormatGridViewItem(item, GridItemColor.BLUE));
lastColor = GridItemColor.BLUE;
}
}
...
private Grid FormatGridViewItem(MyModel currentItem, GridItemColor itemColor)
{
Grid gridItem = new Grid();
#region Grid Item Row Definition and GridItem Setup
RowDefinition itemRowDef = new RowDefinition();
RowDefinition minorButtonRowDef = new RowDefinition();
itemRowDef.Height = new GridLength(72);
minorButtonRowDef.Height = new GridLength(49);
gridItem.RowDefinitions.Add(classPlanRowDef);
gridItem.RowDefinitions.Add(minorButtonRowDef);
gridItem.MaxWidth = 196;
gridItem.Width = 196;
gridItem.Margin = new Thickness(0, 0, 24, 24);
#endregion
#region Button Item
Button btnItem = new Button();
btnItem.BorderThickness = new Thickness(0);
btnItem.Margin = new Thickness(-3, 0, 0, 0);
btnItem.Opacity = 100;
btnItem.MaxWidth = 203;
btnItem.MinWidth = 203;
btnItem.Height = 78;
btnItem.DataContext = currentItem;
if (itemColor == GridItemColor.RED)
btnItem.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 107, 51));
else
btnItem.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 23, 229, 192));
btnItem.Click += btnItem_Click;
TextBlock txtItem = new TextBlock();
txtItem.FontSize = 40;
if (itemColor == GridItemColor.RED)
txtItem.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 91, 31, 8));
else
txtItem.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 3, 97, 80));
txtItem.Opacity = 100;
txtItem.TextAlignment = TextAlignment.Center;
txtItem.Text = currentItem.Name;
txtItem.TextTrimming = TextTrimming.CharacterEllipsis;
btnItem.Content = txtItem;
gridItem.Children.Add(btnItem);
Grid.SetRow(btnItem, 0);
#endregion
#region Grid Minor Buttons Row
Grid minorButtonsRow = new Grid();
minorButtonsRow.Margin = new Thickness(0);
if (itemColor == GridItemColor.RED)
minorButtonsRow.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 107, 51));
else
minorButtonsRow.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 23, 229, 192));
ColumnDefinition btnOneColumnDef = new ColumnDefinition();
ColumnDefinition btnTwoColumnDef = new ColumnDefinition();
btnOneColumnDef.Width = new GridLength(98);
btnTwoColumnDef.Width = new GridLength(98);
minorButtonsRow.ColumnDefinitions.Add(btnOneColumnDef);
minorButtonsRow.ColumnDefinitions.Add(btnTwoColumnDef);
// Button One
Button btnOne = new Button();
btnOne.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 255, 255));
btnOne.BorderThickness = new Thickness(0);
btnOne.MinWidth = 97;
btnOne.MaxWidth = 97;
btnOne.MinHeight = 48;
btnOne.MaxHeight = 48;
btnOne.Margin = new Thickness(0, 0, 1, 0);
btnOne.DataContext = currentItem;
btnOne.Click += btnOne_Click;
ImageBrush imgOne = new ImageBrush();
BitmapImage bitImg;
if (itemColor == GridItemColor.RED)
{
bitImg = new BitmapImage(new Uri("ms-appx:/Assets/Icons/btOneRED.png", UriKind.RelativeOrAbsolute));
btnOne.Style = (Style)this.Resources["btnOneRedStyle"];
}
else
{
bitImg = new BitmapImage(new Uri("ms-appx:/Assets/Icons/btOneBLUE.png", UriKind.RelativeOrAbsolute));
btnOne.Style = (Style)this.Resources["btnOneBlueStyle"];
}
imgOne.ImageSource = bitImg;
imgOne.Stretch = Stretch.UniformToFill;
btnOne.Background = imgOne;
minorButtonsRow.Children.Add(btnOne);
Grid.SetRow(btnOne, 0);
Grid.SetColumn(btnOne, 0);
// END Button One
// Button Two
Button btnTwo = new Button();
btnTwo.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 255, 255));
btnTwo.BorderThickness = new Thickness(0);
btnTwo.MinWidth = 97;
btnTwo.MaxWidth = 97;
btnTwo.MinHeight = 48;
btnTwo.MaxHeight = 48;
btnTwo.Margin = new Thickness(1, 0, 0, 0);
btnTwo.DataContext = currentItem;
btnTwo.Click += btnTwo_Click;
ImageBrush imgTwo = new ImageBrush();
BitmapImage bitImgTwo;
if (itemColor == GridItemColor.RED)
{
bitImgTwo = new BitmapImage(new Uri("ms-appx:/Assets/Icons/btTwoRED.png", UriKind.RelativeOrAbsolute));
btnTwo.Style = (Style)this.Resources["btnTwoRedStyle"];
}
else
{
bitImgTwo = new BitmapImage(new Uri("ms-appx:/Assets/Icons/bt_AgendaVerde.png", UriKind.RelativeOrAbsolute));
btnTwo.Style = (Style)this.Resources["btnTwoBlueStyle"];
}
imgTwo.ImageSource = bitImgTwo;
imgTwo.Stretch = Stretch.UniformToFill;
btnTwo.Background = imgTwo;
minorButtonsRow.Children.Add(btnTwo);
Grid.SetRow(btnTwo, 0);
Grid.SetColumn(btnTwo, 1);
gridItem.Children.Add(minorButtonsRow);
Grid.SetRow(minorButtonsRow, 1);
Grid.SetColumn(minorButtonsRow, 0);
// END Button Two
#endregion
return gridItem;
}
If you have DataTemplate done correctly, then you don't need the ItemsPanel template. Can you show the code for DataTemplate? Because with it you can do pretty much everything.
For the colors. Declare brushes on your ViewModel and then assign it to your classes.Then just bind the Background. You only need one for each color.
Color binding: say you have SolidColorBrush property on your model named BgBrush. All you need to do is declare Background property on your control (i.e. grid) as "{Binding BgBrush}"

Scale child back in WPF

I have a Grid which scaled/zoomed with ScaleTransform by slider. At runtime many UIElements are added to this Grid.
I want to show some tooltips, but not scaled! How should I do that?
For the example: Grid has scaleX and scaleY 2, so I set new ScaleTransform(0.5, 0.5), but didn't help. It seems that the most similar value is 0.740.. Why?
Even Grid's LayoutTransform.Inverse is set to scale values 0.5.
XAML:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Height="Auto" Width="Auto" Name="graphScrollViewer" ScrollChanged="graphScrollViewer_ScrollChanged">
<Grid Margin="0,0,0,0" Name="graphGrid" Width="Auto" Height="Auto" ScrollViewer.IsDeferredScrollingEnabled="True" MouseLeftButtonDown="graphGrid_MouseLeftButtonDown" MouseLeftButtonUp="graphGrid_MouseLeftButtonUp" MouseMove="graphGrid_MouseMove">
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=sldZoom, Path=Value}" ScaleY="{Binding ElementName=sldZoom, Path=Value}" />
</Grid.LayoutTransform>
</Grid>
</ScrollViewer>
<Slider Minimum="0.1" Maximum="20" Value="1" x:Name="sldZoom" Panel.ZIndex="10" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,20,20" Height="23" Width="100" ValueChanged="sldZoom_ValueChanged"/>
Code-behind:
(method of Rectangle (MouseEnter event) dynamically added to grid)
private void rect_MouseEnter(object sender, MouseEventArgs e)
{
RectToolTip = new TextBlock();
RectToolTip.HorizontalAlignment = HorizontalAlignment.Left;
RectToolTip.VerticalAlignment = VerticalAlignment.Top;
RectToolTip.TextAlignment = TextAlignment.Center;
RectToolTip.Height = this.HeaderTwoHeight + 1;
RectToolTip.Text = " " + (RectsTasks[(sender as Rectangle)]).Info + " ";
RectToolTip.Background = this.ToolTipBackground;
RectToolTip.Foreground = this.ToolTipFontColor;
RectToolTipBorder = new Border();
RectToolTipBorder.Child = RectToolTip;
RectToolTipBorder.BorderThickness = new Thickness(this.ToolTipBorderThickness);
RectToolTipBorder.BorderBrush = this.ToolTipBorderColor;
RectToolTipBorder.Margin = new Thickness(e.GetPosition((graphGrid)).X + 10, e.GetPosition((graphGrid)).Y + 10, 0, 0);
RectToolTipBorder.VerticalAlignment = System.Windows.VerticalAlignment.Top;
RectToolTipBorder.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
graphGrid.Children.Add(RectToolTipBorder);
RectToolTipBorder.LayoutTransform = RectToolTip.LayoutTransform = new ScaleTransform(????);
Grid.SetZIndex(RectToolTip, 20);
Grid.SetZIndex(RectToolTipBorder, 20);
}
You need to assign the inverse transform to the child element, so that the child will stay intact.
RectToolTipBorder.LayoutTransform = graphGrid.LayoutTransform.Inverse as Transform;

Converting Grid Content to a ListView or Other for use in MVVM Pattern

I have a 5 X 4 Grid (code below) which works as desired for the shape of my data. I recently discovered it is virtually impossible to pass a grid from the View Model to the View and bind it to another grid in XAML and still maintain the MVVM pattern - which is my goal.
The challenge here is that my presentation requires the children to be grouped in single cells with each having, 1 image, and two textblock UI elements.
DataTable, DataSet, GridView, List etc all seem to lack the ability to add multiple child elements to individual row/column cells for display. Unfortunately this is not just simply sticking an image in a column header.
Has anyone found another option for doing similar?
Thanks,
Glenn
Below is the sample grid and an image of the resulting view.
public void FormatGridCell()
{
Random random = new Random();
List<int> randomNumList = new List<int>();
for (int i = 0; i < 50; i++)
randomNumList.Add(random.Next(50));
List<string> columHeader = new List<string>();
columHeader.Add("Pitts");
columHeader.Add("Vans");
columHeader.Add("Lancair");
columHeader.Add("Epic");
List<string> rowHeader = new List<string>();
rowHeader.Add("NORTH");
rowHeader.Add("SOUTH");
rowHeader.Add("EAST");
rowHeader.Add("WEST");
rowHeader.Add("CANADA");
for (int x = 1; x < 5; x++)
{
var engineType= new TextBlock { Text = columHeader[x - 1] };
engineType.SetValue(Grid.RowProperty, 0);
engineType.SetValue(Grid.ColumnProperty, x);
engineType.HorizontalAlignment = HorizontalAlignment.Center;
this.airplaneGrid.Children.Add(engineType);
for (int r = 1; r < 6; r++)
{
var dealerService = new TextBlock { Text = rowHeader[r - 1] };
dealerService.SetValue(Grid.RowProperty, r);
dealerService.SetValue(Grid.ColumnProperty, 0);
dealerService.HorizontalAlignment = HorizontalAlignment.Center;
this.airplaneGrid.Children.Add(dealerService);
for (int i = 1; i < 6; i++)
{
// Bitmap path will be based on Type
var modelImage = new Image { Width = 20, Height = 20 };
var bitmapImage = new BitmapImage(new Uri(#"c:\personal\temp\dog.jpg"));
modelImage.Source = bitmapImage;
modelImage.SetValue(Grid.RowProperty, r);
modelImage.SetValue(Grid.ColumnProperty, i);
modelImage.HorizontalAlignment = HorizontalAlignment.Left;
modelImage.VerticalAlignment = VerticalAlignment.Top;
var mfgName = new TextBlock { Text = "Lancair IV" };
mfgName.SetValue(Grid.RowProperty, r);
mfgName.SetValue(Grid.ColumnProperty, i);
mfgName.HorizontalAlignment = HorizontalAlignment.Center;
var price = new TextBlock { Text = "$" + randomNumList[r + i] };
price.SetValue(Grid.RowProperty, r);
price.SetValue(Grid.ColumnProperty, i);
price.HorizontalAlignment = HorizontalAlignment.Left;
price.VerticalAlignment = VerticalAlignment.Center;
price.Margin = new Thickness(30, 0, 0, 0);
this.airplaneGrid.Children.Add(modelImage);
this.airplaneGrid.Children.Add(mfgName);
this.airplaneGrid.Children.Add(price);
}
}
}
}
This function is not mine. Sorry, forgot the named credit, but a fellow stackoverflow chap provided to this forum.
public static class RandomExtensions
{
public static int NextDouble(
Random random,
double minValue,
double maxValue)
{
return random.Next(10, 50);
}
}
Sorry, I'm too low on the totem pole to submit an image, but run it for a full understanding of the intended layout.
here is the XAML to support the above.
<Grid x:Name="airplaneGrid" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="60"/>
<RowDefinition Height="60"/>
<RowDefinition Height="60"/>
<RowDefinition Height="60"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="175"/>
<ColumnDefinition Width="175"/>
<ColumnDefinition Width="175"/>
<ColumnDefinition Width="175"/>
<ColumnDefinition Width="175"/>
</Grid.ColumnDefinitions>
</Grid>
You could use another Grid (or stackpanel, or whatever type of panel) as the child element in each cell and then add the child elements to that panel
Ok. I placed your solution and mine side to side. It looks like this:
Admittedly, it requires a little bit more tweaking, but you get the main idea.
<ListView ItemsSource="{Binding}" Grid.Column="1">
<ListView.Resources>
<DataTemplate x:Key="CellContentTemplate">
<Border BorderBrush="LightGray" BorderThickness="1">
<DockPanel>
<Image Height="20" Width="20" Source="{Binding ImageSource}" Margin="2"
DockPanel.Dock="Left"/>
<StackPanel>
<TextBlock Text="{Binding Value, StringFormat='${0}'}" Margin="2"/>
<TextBlock Text="{Binding Name}" Margin="2"/>
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Pitts">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Pitts}" ContentTemplate="{StaticResource CellContentTemplate}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Vans">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Vans}" ContentTemplate="{StaticResource CellContentTemplate}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Lancair">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Lancair}" ContentTemplate="{StaticResource CellContentTemplate}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Epic">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Epic}" ContentTemplate="{StaticResource CellContentTemplate}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Code Behind (just random data):
Random random = new Random();
public GridSample() //Window Constructor
{
InitializeComponent();
var names = new[] {"NORTH","SOUTH","EAST","WEST"};
DataContext = names.Select(x => new GridViewModel()
{
Name = x,
Epic = CreateRandomCell(),
Lancair = CreateRandomCell(),
Pitts = CreateRandomCell(),
Vans = CreateRandomCell()
});
}
private CellViewModel CreateRandomCell()
{
return new CellViewModel
{
Name = "Cell" + random.Next(0, 100),
ImageSource = "/ChessPieces/BlackBishop.png",
Value = (decimal) random.Next(0, 100)
};
}
ViewModels:
public class GridViewModel
{
public string Name { get; set; }
public CellViewModel Pitts { get; set; }
public CellViewModel Vans { get; set; }
public CellViewModel Lancair { get; set; }
public CellViewModel Epic { get; set; }
}
public class CellViewModel
{
public string Name { get; set; }
public string ImageSource { get; set; }
public decimal Value { get; set; }
}
See? pure MVVM, clean, beautiful solution.

Categories