I am using XAML and MVVM pattern for an application.
In part of my application I have a window split into 2 parts, a left column and right hand column/area
In the left column are a row of buttons ( generated on loading the window )
The right column/area will display a group of buttons depending on which button the user clicks in the left column, so for example say I have 4 department buttons in the left column, each department button will have a different number of stock items.
If I click button 1 in the left column, I do some code in the viewmodel to fetch the names of items in that department. And then I build a new observableCollection to display in the right column/area.
So this isnt a problem, the right amount of buttons get generated each time ok.
However when I try to change the background colour dynamically in the ViewModel, the colour is NOT upodated in the view.
The strange thing is, I can change the content, forecolour and other properties but just not the background colour. It appears the background will only generate correctly if loaded and run time. I cant change it otherwise while using the window.
I have tried Brushes, creating and assigning new style and even clearing the dependancy property of the button ( .ClearValue(Button.BackgroundProperty) )
Would any one know how i can get the background to change colour while the window is open and when i want to generate a set of buttons dynamically in my viewmodel?
Many thanks all... I have attached my XAML and C# snippet, the
XAML :
<dxd:DockLayoutManager Name="dlSalesScreen">
<dxd:DockLayoutManager.LayoutRoot>
<dxd:LayoutGroup Name="Root" Orientation="Horizontal" AllowSplitters="False">
<dxd:LayoutPanel AllowClose="False" AllowRename="False"
Caption="Departments" HorizontalScrollBarVisibility="Hidden"
CaptionAlignMode="AutoSize"
CaptionImageLocation="BeforeText" ShowPinButton="False" >
<!-- Scrollviewer for department buttons-->
<ScrollViewer x:Name="deptScrollviewer" Grid.Row="0" Grid.Column="0" Width="185" Height="Auto" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" PanningMode="VerticalOnly">
<ItemsControl ItemsSource="{Binding Departments}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel VerticalAlignment="Top" Height="Auto" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</dxd:LayoutPanel>
<dxd:LayoutPanel AllowClose="False" AllowRename="False"
Caption="Available stock in department" Width="Auto"
CaptionAlignMode="AutoSize"
CaptionImageLocation="BeforeText" ShowPinButton="False">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<!-- Scrollviewer for stock buttons-->
<ScrollViewer x:Name="stockScrollViewer" Grid.Row="0" Width="Auto" Height="Auto" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" PanningMode="VerticalOnly">
<ItemsControl ItemsSource="{Binding StockItems, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel VerticalAlignment="Top" HorizontalAlignment="Left" Orientation="Horizontal" Width="400" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
<Rectangle Grid.Row="1" Margin="0,0,0,0" Height="Auto" Fill="{StaticResource BottomRectangleGradient}" />
<Grid Name="gridButtonHolder" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<GroupBox x:Name="grpStockItem" Grid.Column="0" Header="Selected Item" HorizontalAlignment="Left" Width="200" >
<Label x:Name="lblStockName" Content="{Binding SelectedStockItemLabel}" HorizontalAlignment="Left" />
</GroupBox>
<Button Name="btnSave" Content="Apply" Command="{Binding ConfirmSelectionCommand}" dxc:ThemeManager.ThemeName="Office2007Blue" Grid.Column="1" Width="110" Height="42" Margin="0,8,0,0" />
<Button Name="btnClose" Content="Cancel" dxc:ThemeManager.ThemeName="Office2007Blue" Grid.Column="2" Width="110" Height="42" Margin="0,8,0,0" />
</Grid>
</Grid>
</dxd:LayoutPanel>
</dxd:LayoutGroup>
</dxd:DockLayoutManager.LayoutRoot>
</dxd:DockLayoutManager>
C#
void DeptClicked(object sender, RoutedEventArgs e)
{
SelectedDeptID = Convert.ToInt32(((Button)sender).Tag.ToString());
_stockButtons = new ObservableCollection<Button>();
if (StockItemCount > 0)
{
for (int i = 0; i < StockItemCount; i++)
{
//_stockButtons.Add(new Button());
Button btn = new Button();
btn.Background = Brushes.Aquamarine;
btn.Height = 100;
btn.Width = 100;
btn.Content = i.ToString();
_stockButtons.Add(btn);
}
}
RaisePropertyChanged("StockItems");
}
public ObservableCollection<Button> Departments
{
get
{
if (_deptButtons == null)
{
_deptButtons = new ObservableCollection<Button>();
for (int i = 0; i < DeptCount; i++)
{
Button button = new Button();
button.Content = DepartmentNames[i];
button.Tag = DepartmentIDs[i].ToString();
button.Click += new RoutedEventHandler(DeptClicked);
button.Width = 128;
button.Height = 100;
_deptButtons.Add(button);
}
}
return _deptButtons;
}
}
Try something like that:
Button btn = new Button();
btn.Background = Brushes.Green;
btn.Height = 100; btn.Width = 100;
btn.Content = i.ToString();
ThemeManager.SetThemeName(btn, "None");
_stockButtons.Add(btn);
Class ThemeMagager is in namespace DevExpress.Xpf.Core.
Related
I am currently trying to find/implement a WPF control, which is a combination of a Grid and a StackPanel. That means, I like to have two columns with several items. An item is another control (e.g. single Label, TextBox with label in a panel, ...).
If an item is collapsed, the empty space should be filled with the next item, means I have always as less space used in the control as possible (without gaps between the single items).
I attached two images how it should look like.
Initial:
Item4 is collapsed (notice the shift of following up items):
Does anybody have an idea or experience how to do something like that?
you can use a ListView that uses a StackPanel or a DockPanel as ItemTemplate.
This is an example (simplified) of what I use to display an observable collection of objects in a list with Grid and DockPannel:
<ListView x:Name="lbxDroppedDatas" SelectionMode="Single" AllowDrop="True" BorderThickness="0" Padding="0" Margin="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="lbxDroppedDatas_SelectionChanged" PreviewKeyDown="lbxDroppedDatas_PreviewKeyDown" PreviewMouseRightButtonDown="lbxDroppedDatas_PreviewMouseRightButtonDown" >
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel Grid.Row="0" Width="{Binding Path=ActualWidth, ElementName=Container}" Height="40" Margin="1" LastChildFill="True">
<CheckBox DockPanel.Dock="Left" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
<Label Content="{Binding Name}" Foreground="{Binding LineBrush}" FontWeight="Bold" FontSize="12" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="0" MouseEnter="Label_MouseEnter" MouseLeave="Label_MouseLeave"/>
<TextBox DockPanel.Dock="Right" Width="60" MaxLength="14" Text="{Binding CurrentValue, StringFormat=N}" Margin="0,0,33,0" Background="Transparent" Foreground="{Binding LineBrush}" BorderBrush="{Binding LineBrush}" BorderThickness="1" VerticalAlignment="Center" HorizontalAlignment="Right" IsEnabled="False"/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" VerticalAlignment="Stretch" Margin="0"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
You could bind the visibility of your list element to a collapsed or visible property.
I'd solve this problem in the following way:
start with creating a grid with two stack panels (the grid resides within a UserControl or any other placeholder):
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel x:Name="LeftPanel" x:FieldModifier="private" Orientation="Vertical" />
<StackPanel x:Name="RightPanel" x:FieldModifier="private" Grid.Column="1" Orientation="Vertical" />
</Grid>
to control your items, create a list of items, preferably within the code of your UserControl:
private List<FrameworkElement> m_items = new List<FrameworkElement>();
for the items you don't want to be visible set the Visibility to Hidden or Collapsed.
you'd need some method that will select the visible items and place them alternating to the left and right panel. I've came up with some quick method that you need to call each time your list changes (an item is added or removed, visibility of an item is changed):
public void SortItems()
{
this.LeftPanel.Children.RemoveRange(0, this.LeftPanel.Children.Count);
this.RightPanel.Children.RemoveRange(0, this.RightPanel.Children.Count);
this.m_items.Where(i => i.Visibility == Visibility.Visible).ToList().ForEach((i) => { (this.LeftPanel.Children.Count == this.RightPanel.Children.Count ? this.LeftPanel : this.RightPanel).Children.Add(i); } );
}
The method simply removes all children of the stack panels and then traverses through the items' list choosing only those which are Visible and adds one to the left panel if both panels have the same amount of items in them and to the right panel otherwise.
If you need some other way of selecting into which panel the following item should be added (e.g. ActualHeight) simply change the condition that is selecting the panels.
If you want to make this method more elegant you can add some events or dependency properties that will call SortItems automatically. Anyway, it's a good start.
Thank you very much for all the different solutions. Finally I solved it with the suggestion from Sinatr. So I created my own panel and override the ArrangeOverride:
protected override Size ArrangeOverride(Size finalSize)
{
List<UIElement> visibleItems = new List<UIElement>();
double xColumn1 = 0;
double xColumn2 = (finalSize.Width / 2) + (WIDTH_COLUMN_SEPERATOR / 2);
double y = 0;
double columnWidth = (finalSize.Width - WIDTH_COLUMN_SEPERATOR) / 2;
for (int i = 0; i < InternalChildren.Count; i++)
{
UIElement child = InternalChildren[i];
if (child.Visibility != Visibility.Collapsed)
{
visibleItems.Add(child);
}
}
for (int i = 0; i < visibleItems.Count; i++)
{
if (i >= (visibleItems.Count - 1))
{
visibleItems[i].Arrange(new Rect(xColumn1, y, columnWidth, visibleItems[i].DesiredSize.Height));
}
else
{
UIElement leftItem = visibleItems[i];
UIElement rightItem = visibleItems[i + 1];
double rowHeight = leftItem.DesiredSize.Height > rightItem.DesiredSize.Height ? leftItem.DesiredSize.Height : rightItem.DesiredSize.Height;
leftItem.Arrange(new Rect(xColumn1, y, columnWidth, rowHeight));
rightItem.Arrange(new Rect(xColumn2, y, columnWidth, rowHeight));
y += rowHeight;
i++;
}
}
return finalSize;
}
I also created my own UserControl for the Items:
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="captionLabel" Grid.Row="0" Content="{Binding Caption}"/>
<ContentPresenter x:Name="inputMask" Grid.Row="1" Content="{Binding InputMask, ElementName=userControlBRAIN2AttributePanelItem}" />
</Grid>
So I get te following result (from my test application):
enter image description here
with collapsed item 3:
enter image description here
I'm surprised that no one sugested the use of an UniformGrid.
All you have to do is declar an UniformGrid, set Columns to 2 and add your items. Items that are collapsed should have its Visibility set to Collapsed (duh).
Here's an example:
<UniformGrid Columns="2"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="Item 1 " />
<TextBlock Text="Item 2 " />
<TextBlock Text="Item 3 " />
<TextBlock Text="Item 4 " />
</UniformGrid>
Will produce the following result:
And when the Visibility of the second TextBlock is set to Collapsed, here's what it looks like:
I have a window that I'm basically building ghetto minesweeper in. I have a grid that I feed a jagged array into, set up so that it will adapt to any change in the size of the array (no hard set values or rows/columns). Over top of that, I have a grid of blank buttons that simply adapts in size to the grid below.
When you click a button, it hides revealing the value under it, and I need some way to return the position of the button clicked, so I can compare against the original jagged array to find out whether not the item was a bomb. (this would also help me for doing a fill action on empty tiles). But given how I have it set up, the Grid.GetRow or Grid.GetColumn just return 0's.
Does anyone know how I can get the array position (preferably row and column) from the setup that I have?
XAML Below, the C# click events follow it.
<Window x:Class="MinesweeperWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Minesweeper" SizeToContent="WidthAndHeight" Height="Auto" Width="Auto">
<Window.Resources>
<DataTemplate x:Key="Buttons_Template">
<Button Content=""
Height="20"
Width="20"
Margin="0,0,0,0"
Visibility="Visible"
Click="ButtonClick"
MouseRightButtonUp="RightClick"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_2">
<TextBlock Text="{Binding}"
Height="20"
Width="20"
Margin="0,0,0,0"
FontFamily="Rockwell"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="5"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
<DataTemplate x:Key="Buttons_Template2">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource Buttons_Template}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<TextBlock x:Name="RemainingMines" HorizontalAlignment="Left" />
<TextBlock x:Name="Difficulty" HorizontalAlignment="Center" />
<TextBlock x:Name="Timer" HorizontalAlignment="Right" />
</Grid>
<Grid Name="ResetButton" Grid.Row="1">
<Button Name="Reset" Content="Reset"/>
</Grid>
<Grid Name="GridBoard" ShowGridLines="True" Grid.Row="2">
<ItemsControl x:Name="GridItems" ItemTemplate="{DynamicResource DataTemplate_1}"/>
</Grid>
<Grid Name="ButtonsBoard" ShowGridLines="True" Grid.Row="2">
<ItemsControl x:Name="ButtonItems" ItemTemplate="{DynamicResource Buttons_Template2}"/>
</Grid>
</Grid>
</Window>
Click Methods in C#
private void ButtonClick(object sender, RoutedEventArgs e)
{
int col = Grid.GetColumn((Button)sender); //this just returns 0
int row = Grid.GetRow((Button)sender); //this just returns 0
Button source = e.Source as Button;
source.Visibility = Visibility.Hidden;
Console.WriteLine("L: {0} x {1}", col, row); //prints L: 0 x 0
}
private void RightClick(object sender, RoutedEventArgs e)
{
int col = Grid.GetColumn((Button)sender); //this just returns 0
int row = Grid.GetRow((Button)sender); //this just returns 0
Button source = e.Source as Button;
if(source.Content.Equals(""))
{
source.Content = "\u2691";
}
else
{
source.Content = "";
}
Console.WriteLine("R: {0} x {1}", col, row); //prints R: 0 x 0
}
Any help would be appreciated on this.
You need to use appropriate control for buttons to host. In your xaml you are using items control inside Grid. But Items control do not have row and column index. Thats why you are not able to get the index.
Use UniformGrid or some relevant control.
You can refer this article
https://stackoverflow.com/a/13588066/5273015
Will help you a lot in other assignments as well
i populated some text ( i name them as questions) from database but in my wrap panel i can only display 3 questions , the rest of the questions are being cut-off , i have more than 3 questions , how can i do a paging in wrap panel to display the rest of the question on the panel itself? i populate the questions by for loop like this:
for( int i= 0 ; i<lstQuestion.Count()-2; i++)
{
TextBlock tb = new TextBlock(); // Question
tb.FontSize = 19;
tb.FontWeight = FontWeights.Bold;
tb.Text = lstQuestion[i].QuestionContent;
tb.TextWrapping = TextWrapping.Wrap;
wrapPanel1.Children.Add(tb);
TextBox tbox = new TextBox();
if (lstQuestion[i].Answer.Trim().Length > 0) // Textbox for user to input answer in every question
{
tbox.FontSize = 19;
tbox.Width = 250;
tbox.Height = 50;
tbox.PreviewDrop += new DragEventHandler(tbox_PreviewDrop);
tbox.Focusable = false; // Disallow user to input anything into it.
wrapPanel1.Children.Add(tbox);
}
answers.Add(lstQuestion[i].Answer);
if (lstQuestion[i].QuestionNo != lstQuestion[i + 1].QuestionNo) // add spacing between question
{
StackPanel sp = new StackPanel();
sp.Width = 1010;
wrapPanel1.Children.Add(sp);
Label spacing = new Label();
spacing.Width = 1010;
spacing.Content = "";
wrapPanel1.Children.Add(spacing);
}
} // end of for each loop.
And in my xaml :
<Grid>
<WrapPanel HorizontalAlignment="Center" Name="wrapPanel1" VerticalAlignment="Center" Height="400" Width="1038" Margin="0,77,0,43" />
<WrapPanel Height="80" HorizontalAlignment="Center" Name="wrapPanel2" VerticalAlignment="Top" Background="Aquamarine" Width="1000">
</WrapPanel>
<Button Content="Check" Height="37" HorizontalAlignment="Center" Name="button1" VerticalAlignment="Bottom" Width="90" FontSize="24" Margin="474,0" Click="button1_Click" />
</Grid>
Wrappanel1 is where i put my questions and textbox ( wrap panel 1 is the panel that i want to do paging in ) , wrappanel2 is another panel where choices of answers are there.
As you can see from the grey arrow , there is still more text , but it just stops there at the end of the scroll.
Put your wrapPanel1 inside a ScrollViewer.
<ScrollViewer VerticalAlignment="Center" HorizontalAlignment="Center" Height="400" Width="1038">
<WrapPanel Name="wrapPanel1" />
</ScrollViewer>
Try arranging your UI in XAML with RowDefinitions
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" HorizontalAlignment="Center" Name="wrapPanel2" Background="Aquamarine" Width="1000"></WrapPanel>
<ScrollViewer Grid.Row="1" Height="400" Width="1038" CanContentScroll="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<WrapPanel Name="wrapPanel1"/>
</ScrollViewer>
<Button Grid.Row="2" Content="Check" Margin="5" HorizontalAlignment="Center" Name="button1" VerticalAlignment="Bottom" Width="90" FontSize="24" Click="button1_Click" />
</Grid>
The standard GridApp template is as follows:
Variable Sized Grouped GridView template is as follows:
How to make a template for your application, so that it looks like this:
For example, this design in all applications Bing for windows 8:
Code for Variable Sized Grouped GridView template:
<UserControl.Resources>
<!-- Collection of grouped items displayed by this page -->
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="Items"
d:Source="{Binding ItemGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
<DataTemplate x:Key="CustomTileItem">
<Grid >
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel VerticalAlignment="Bottom" >
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="30" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</UserControl.Resources>
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Grid.Column="1" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
<!-- Horizontal scrolling grid used in most view states -->
<ScrollViewer
x:Name="itemGridScrollViewer"
AutomationProperties.AutomationId="ItemGridScrollViewer"
Grid.Row="1"
Margin="0,-3,0,0"
Style="{StaticResource HorizontalScrollViewerStyle}">
<local:MyGridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Margin="116,0,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource CustomTileItem}"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<local:MyGridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</local:MyGridView.ItemsPanel>
<local:MyGridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="1,0,0,6">
<Button
AutomationProperties.Name="Group Title"
Content="{Binding Title}"
Click="Header_Click"
Style="{StaticResource TextButtonStyle}"/>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid ItemWidth="75" ItemHeight="150" Orientation="Vertical" Margin="0,0,80,0" MaximumRowsOrColumns="3"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</local:MyGridView.GroupStyle>
</local:MyGridView>
</ScrollViewer>
and:
public class MyGridView : GridView
{
private int rowVal;
private int colVal;
private Random _rand;
private List<Size> _sequence;
public MyGridView()
{
_rand = new Random();
_sequence = new List<Size> {
LayoutSizes.PrimaryItem,
LayoutSizes.SecondarySmallItem, LayoutSizes.SecondarySmallItem,
LayoutSizes.SecondarySmallItem,
LayoutSizes.SecondaryTallItem,
LayoutSizes.OtherSmallItem, LayoutSizes.OtherSmallItem, LayoutSizes.OtherSmallItem
};
}
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
SampleDataItem dataItem = item as SampleDataItem;
int index = -1;
if (dataItem != null)
{
index = dataItem.Group.Items.IndexOf(dataItem);
}
if (index >= 0 && index < _sequence.Count)
{
colVal = (int)_sequence[index].Width;
rowVal = (int)_sequence[index].Height;
}
else
{
colVal = (int)LayoutSizes.OtherSmallItem.Width;
rowVal = (int)LayoutSizes.OtherSmallItem.Height;
}
VariableSizedWrapGrid.SetRowSpan(element as UIElement, rowVal);
VariableSizedWrapGrid.SetColumnSpan(element as UIElement, colVal);
}
}
public static class LayoutSizes
{
public static Size PrimaryItem = new Size(6, 2);
public static Size SecondarySmallItem = new Size(3, 1);
public static Size SecondaryTallItem = new Size(3, 2);
public static Size OtherSmallItem = new Size(2, 1);
}
For example with "Variable Sized Grouped GridView template", we can combine the rows or columns, and how to set the first element height = "auto", and all other elements that have different widths and heights, but grouped as "Variable Sized Grouped GridView template"?
View this post:
http://blogs.msdn.com/b/synergist/archive/2012/09/25/windows-store-app-xaml-gridview-with-variable-templates.aspx
I think this is what you need.
I have a grid that I need to put into a border, doing this via XAML is easy
but how do I do this via C#?
everything that I have found thus far wants to add the border around each cell.
I need it to come out looking the same way XAML does it, please help!
I can not get the XAML to post correctly here:
<Border Grid.Column="1"
Grid.Row="0"
Background="AliceBlue"
BorderBrush="Black"
BorderThickness="4"
x:Name="Side6"
Visibility="Collapsed">
<UIElement.Projection>
<PlaneProjection RotationY="-90" />
</UIElement.Projection>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Column="2" Grid.Row="1" Click="RotateRight_Click">
<Button.Content>
<StackPanel>
<TextBlock HorizontalAlignment="Center">Rotate Right</TextBlock>
<TextBlock HorizontalAlignment="Center">To</TextBlock>
<TextBlock HorizontalAlignment="Center">Side 4</TextBlock>
</StackPanel>
</Button.Content>
</Button>
<Button Grid.Column="0" Grid.Row="1" Click="RotateLeft_Click">
<Button.Content>
<StackPanel>
<TextBlock HorizontalAlignment="Center">Rotate Left</TextBlock>
<TextBlock HorizontalAlignment="Center">To</TextBlock>
<TextBlock HorizontalAlignment="Center">Side 2</TextBlock>
</StackPanel>
</Button.Content>
</Button>
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Text="Side 6">
</TextBlock>
</Grid>
</Border>
Here is the C# code that I'm using, maybe you can see what I am doing wrong?
public static void panelMain(string strPassGridName, System.Windows.Media.Color mcPassColor,
int intRowProperty, int intColumnProperty, Visibility vVisibility,
string[] strButtonTitles, Grid passLayoutRoot, Canvas passCanvas)
{
Grid panelGrid = new Grid();
panelGrid.Name = strPassGridName;
panelGrid.Background = new SolidColorBrush(mcPassColor);
panelGrid.SetValue(Grid.RowProperty, intRowProperty);
panelGrid.SetValue(Grid.ColumnProperty, intColumnProperty);
panelGrid.Visibility = vVisibility;
RowDefinition row1 = new RowDefinition();
row1.Height = new GridLength(100, GridUnitType.Auto);
panelGrid.RowDefinitions.Add(row1);
ColumnDefinition column1 = new ColumnDefinition();
column1.Width = new GridLength(100);
panelGrid.ColumnDefinitions.Add(column1);
passLayoutRoot.Children.Add(panelGrid);
}
I figured it out, I needed to create the border first then add the grid to the border.
One major difference is that I could not reference the border object directly, I needed to "find it"
Border findBorder = passLayoutRoot.FindName("bd" + strPassGridName) as Border;
if (findBorder == null)
{ }
else
{
findBorder.Child = panelGrid;
}
This worked perfectly....
Thanks to all that attempted to help
You can do it as below,
Border gridBorder = new Border();
gridBorder.BorderBrush = new SolidColorBrush(Colors.Black);
gridBorder.BorderThickness = new Thickness(4);
gridBorder.Child = new Grid(); //Your grid here
LayoutRoot.Children.Add(border); // ParentGrid(layout) holding the border