In UWP I have GridView. That GridView has ItemTemplate like this:
<Page.Resources>
<DataTemplate x:Key="Template" x:DataType="local:ModelClass">
<local:CustomUserControl
Model="{x:Bind Mode=OneWay}"/>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView x:Name="gvMain" ItemTemplate="{StaticResource Template}" SelectionChanged="gvMain_SelectionChanged">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical"
Margin="0,0,0,-10"
MaximumRowsOrColumns="1"
ItemWidth="50"
ItemHeight="50"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
The usercontrol is like this:
<Grid x:Name="gridMain" Width="50" Height="50">
<Grid VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0, 0, -10, 0" Width="20" Height="20" Background="Pink"/>
</Grid>
And in codebehind:
public ModelClass Model
{
get { return (ModelClass)GetValue(ModelProperty); }
set { SetValue(ModelProperty, value); SetBackground(); }
}
public static readonly DependencyProperty ModelProperty =
DependencyProperty.Register("Model", typeof(ModelClass), typeof(CustomUserControl), new PropertyMetadata(new ModelClass()));
private void SetBackground()
{
if (Model == null)
{
return;
}
gridMain.Background = Model.BackgroundColor;
}
public CustomUserControl()
{
this.InitializeComponent();
}
I am populating the GridView like this:
List<ModelClass> list = new List<ModelClass>();
ModelClass mc = new ModelClass();
mc.BackgroundColor = new SolidColorBrush(Colors.Red);
ModelClass mc1 = new ModelClass();
mc1.BackgroundColor = new SolidColorBrush(Colors.Blue);
ModelClass mc2 = new ModelClass();
mc2.BackgroundColor = new SolidColorBrush(Colors.Yellow);
ModelClass mc3 = new ModelClass();
mc3.BackgroundColor = new SolidColorBrush(Colors.Green);
list.Add(mc);
list.Add(mc1);
list.Add(mc2);
list.Add(mc3);
gvMain.ItemsSource = list;
And what it looks like is this:
On each item there is a small square in upper right corner, colored in pink.
When I click on some item, I want that item to overlap every other items, so my pink square will be visible.
How to change Z-index of GridView items in this case?
How to change Z-index of GridView items in this case?
If you want to change the GridViewItem's Z-Index, you might think about using canvas relevant panel as the GridView's ItemsPanel.
Then, in your SelectionChanged event handler method, you could use the Canvas.SetZIndex(UIElement, index) method to set current selected item's Canvas.ZIndex. It would get your effect that you want.
But, if you used the general Canvas control as the GridView's ItemsPanel. You would find that the items would not be shown as the general items list.
As a result, in your case, you also would need to define your custom panel. You could need to rearrange the items in it.
I've made a simple for your reference:
<GridView x:Name="gvMain" SelectionChanged="gvMain_SelectionChanged">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<local:CustomPanel></local:CustomPanel>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridViewItem >
<Rectangle Fill="Red" Width="50" Height="50"></Rectangle>
</GridViewItem>
<GridViewItem >
<Rectangle Fill="Blue" Width="50" Height="50" ></Rectangle>
</GridViewItem>
<GridViewItem>
<Rectangle Fill="Yellow" Width="50" Height="50"></Rectangle>
</GridViewItem>
</GridView>
public class CustomPanel:Canvas
{
protected override Size MeasureOverride(Size availableSize)
{
Size s = base.MeasureOverride(availableSize);
foreach (UIElement element in this.Children)
{
element.Measure(availableSize);
}
return s;
}
protected override Size ArrangeOverride(Size finalSize)
{
this.Clip = new RectangleGeometry { Rect = new Rect(0, 0, finalSize.Width, finalSize.Height) };
Double position = 0d;
foreach (UIElement item in this.Children)
{
if (item == null)
continue;
Size desiredSize = item.DesiredSize;
if (double.IsNaN(desiredSize.Width) || double.IsNaN(desiredSize.Height)) continue;
var rect = new Rect(0, position, desiredSize.Width, desiredSize.Height);
item.Arrange(rect);
TranslateTransform compositeTransform = new TranslateTransform();
compositeTransform.X = position / 2;
item.RenderTransform = compositeTransform;
position += desiredSize.Width;
}
return finalSize;
}
}
private void gvMain_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
GridViewItem item = (sender as GridView).SelectedItem as GridViewItem;
if (item != null)
{
Canvas.SetZIndex(item,index);
}
}
This just is a simple code sample, you could do more custom behavior in your custom panel.
The following are the effect screenshots:
Related
I was intending to overlay multiple Canvas, between 4 and 6 layers, on top of a large Image, in order that I can set all objects in a given Canvas as visible or invisable with the simplicity of a show or Hide routine in a layer class. UpdateLayers simply has a set of calls to each layer.Update(). In the case of the settlementNames layer, it would seem that the Update code is not doing its job. It is supposed work like this;
private void ShowCities_Click(object sender, RoutedEventArgs e)
{
UpdateLayers();
settlements.Show(Settlements);
settlementNames.Show(SettlementNames);
}
public void Show(Canvas canvas)
{
canvas.Visibility = Visibility.Visible;
}
This worked perfectly with the first canvas containing icon sized BitmapImages at ZIndex 1 (the large Image is essentially the background with ZIndex 0). When I tried to add a further canvas at ZIndex 2, the code steps through as expected but does not show the contents. This time the contents is a set of TextBlocks.
The AssociatedCanvas property in the code, has been checked and is the correct Canvas instance, which was laid down in the XAML main window.
public void Update(string layerSelectSqlQuery, LayerType layerType)
{
DataTable layerDataTable = null;
int x = -1;
int y = -1;
string label;
using (MySqlClientWrapper db = new MySqlClientWrapper("Server = localhost; Database = tribes;Uid = root;Pwd = xxxxxxxxx;"))
{
// TODO add population column - and filter to those settlements considered cities.
layerDataTable = db.GetDataTable(layerSelectSqlQuery);
}
AssociatedCanvas.Children.Clear();
foreach (DataRow dataRow in layerDataTable.Rows)
{
x = (int)dataRow["MapX"];
y = (int)dataRow["MapY"];
label = dataRow["Name"].ToString();
if (x != -1 && y != -1)
{
switch (layerType)
{
case LayerType.Settlements:
DrawBitmapImage(x, y);
break;
case LayerType.SettlementNames:
WriteLabel(x, y, label, Color.FromRgb(0, 0, 0));
break;
case LayerType.Units:
break;
case LayerType.UnitNames:
break;
default:
break;
}
}
}
}
Public void WriteLabel(int x, int y, string text, Color color)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = text;
textBlock.Foreground = new SolidColorBrush(color);
Canvas.SetLeft(textBlock, x);
Canvas.SetTop(textBlock, y);
AssociatedCanvas.Children.Add(textBlock);
}
The XAML looks like this in part:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--<Slider Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Left" Minimum="1" x:Name="slider" />-->
<ScrollViewer Name="mapScroller" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid Name="grid" RenderTransformOrigin="0.5,0.5">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform x:Name="scaleTransform" />
</TransformGroup>
</Grid.LayoutTransform>
<Viewbox Grid.Column="0" Grid.Row="0" >
<Image x:Name="MainMap" UseLayoutRounding="True" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center"
MouseLeftButtonUp="MainMap_MouseLeftButtonUp" Source="{Binding MainTerrainMap}"></Image>
</Viewbox>
<Canvas x:Name="Settlements" Panel.ZIndex="1" />
<Canvas x:Name="SettlementNames" Panel.ZIndex="2" >
</Canvas>
</Grid>
</ScrollViewer>
</Grid>
I'm making an MenuItem dynamic in a PCL project, constructing this when the list view are appearing.
This is my xaml:
<ListView x:Name="ListParceiros" RowHeight="60" ItemTapped="Parceiros_Tapped" Style="{StaticResource listViewGlobalStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Appearing="OnItemAppearing">
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill" BackgroundColor="#fff">
<StackLayout Orientation="Vertical">
<Label Text = "{Binding Nome}" FontSize="24" AbsoluteLayout.LayoutBounds="0.25, 0.25, 400, 40"/>
<Label Text = "{Binding CpfCnpj}" AbsoluteLayout.LayoutBounds="50, 35, 200, 25"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And my cs file:
private void OnItemAppearing(object sender, EventArgs e)
{
ViewCell theViewCell = (ViewCell)sender;
var item = theViewCell.BindingContext as Pessoa;
theViewCell.ContextActions.Clear();
if (item != null)
{
var pessoaVinculo = _pessoaVinculoRepository.Get(w => w.PessoaId == item.PessoaId && w.NegocioId == App.CurrentUser.NegocioId);
if (pessoaVinculo.NegocioAtivo)
{
var desativarAction = new MenuItem { Text = "Desativar", IsDestructive = true };
desativarAction.SetBinding(MenuItem.CommandParameterProperty, new Binding("."));
desativarAction.Clicked += DesativarParceiro;
var servicoAction = new MenuItem { Text = "Serviços" };
servicoAction.SetBinding(MenuItem.CommandParameterProperty, new Binding("."));
servicoAction.Clicked += CallServicos;
theViewCell.ContextActions.Add(desativarAction);
theViewCell.ContextActions.Add(servicoAction);
}
else
{
var aceitarVinculoAction = new MenuItem { Text = "Aceitar Vinculo" };
aceitarVinculoAction.SetBinding(MenuItem.CommandParameterProperty, new Binding("."));
aceitarVinculoAction.Clicked += AceitarConvite;
theViewCell.ContextActions.Add(aceitarVinculoAction);
}
}
}
When I try to access the MenuItem in Android it's work fine, but in iOS the MenuItem are not working.
How could i make this work?
This can be solved using two DataTemplates, one for each case, each one with the needed ContextActions, then use DataTemplateSelector to show the right DataTemplate.
Create your DataTemplateSelector and override the OnSelectTemplate method returning the right DataTemplate depending on your condition (pessoaVinculo.NegocioAtivo in your case).
Know more about DataTemplateSelector in
https://developer.xamarin.com/guides/xamarin-forms/templates/data-templates/selector
I want to implement the following: I have an empty window in the beginning with 3 buttons. When I click a button, I want to generate Size*Size buttons in the window. For button 1, Size=6, for button 2 Size=8 and for button 3 Size=0, so I thought I'd create a UniformGrid and bind its size to Size, so I can change the number of buttons present. Initially, Size would be 0, so no buttons can be seen, then when Size changes, the buttons appear. This, however, doesn't work. I'm trying:
<Window x:Class="project.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="500" Width="700">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Menu Grid.Column="1" Margin="38,0,187,430" Background="White">
<MenuItem Header="Level 1" FontFamily="Roboto" Height="32" Width="65"
Command="{Binding Lvl1Command}"/>
<MenuItem Header="Level 2" FontFamily="Roboto" Height="32" Width="65"
Command="{Binding Lvl2Command}"/>
<MenuItem Header="Level 3" FontFamily="Roboto" Height="32" Width="65"
Command="{Binding Lvl3Command}"/>
</Menu>
<ItemsControl Grid.Column="2" ItemsSource="{Binding Fields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding Size}" Columns="{Binding Size}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Focusable="False" RenderTransformOrigin="0.5, 0.5"
Width="30" Height="25" FontSize="24" FontWeight="Bold">
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
Size is initially 0, Lvl1Command changes Size to 6, Lvl2Command to 8 etc. Fields is just a data structure storing some properties that will affect the style of the button. How could/should I modify this so that when Size changes, the number of appearing Buttons does too? Thank you!
EDIT
In the ViewModel constructor:
Lvl1Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Easy); });
Lvl2Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Medium); });
Lvl3Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Hard); });
And SetUpGame() looks like this (Field included):
private void SetUpGame(MLModel.Level level)
{
UpCommand = new DelegateCommand(param => { _model.MoveUp(); RefreshTable(); });
DownCommand = new DelegateCommand(param => { _model.MoveDown(); RefreshTable(); });
LeftCommand = new DelegateCommand(param => { _model.MoveLeft(); RefreshTable(); });
RightCommand = new DelegateCommand(param => { _model.MoveRight(); RefreshTable(); });
// időzítő létrehozása
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += new EventHandler(Timer_Tick);
_timer.Start();
_model.SetLevel(level);
_model.NewGame();
Fields = new ObservableCollection<MLField>();
for (Int32 i = 0; i < _model.Table.Size; i++)
{
for (Int32 j = 0; j < _model.Table.Size; j++)
{
Fields.Add(new MLField
{
Text = _model.Table[i, j],
X = i,
Y = j,
Number = i * _model.Table.Size + j
});
}
}
RefreshTable();
}
And then Size:
public Int32 Size { get { return _model.Size; } }
The ViewModel must implement INotifyPropertyChanged. Add this code:
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Then, if you want to raise notifications for changes on the Size property, write it this way:
public int Size
{
get { return _Size; }
set
{
if (_Size != value)
{
_Size = value;
NotifyPropertyChanged();
}
}
}
private int _Size;
Also, the Fields collection is initially null, and when you instantiate it in the SetupGame, no notification is raised so the View is still bound to the null reference. You have 2 options:
1) initialize the Fields collection in the constructor. This way, when the ViewModel is passed to the View, the collection is ready to be bound to the ItemsControl. It is not necessary to fill the collection in the constructor, just to instantiate it.
2) implement the Fields property in the same way the Size is:
public ObservableCollection<MLField> Fields
{
get { return _Fields; }
set
{
if (_Fields != value)
{
_Fields = value;
NotifyPropertyChanged();
}
}
}
private ObservableCollection<MLField> _Fields;
This way, you can set a new instance of the collection every time you want, and the ItemsControl binding will update consequently.
I am a new developer on Windows Phone 8.1, I am try to reach a specific ListView item from the ListView collection and be able to color it or color the TextBock inside of it, But I can't reach the item or reach any of items inside of ListView, Please take a look for my below code :
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
SQLiteRT db1 = new SQLiteRT();
var db_connection = await db1.Connection("MyDB.sqlite");
List<MyTBL> t_list = db1.GetTable("SELECT * FROM MyTBL LIMIT 4 ORDER BY RANDOM() ;");
db_connection.Close();
LV_Options.ItemsSource = t_list;
}
// my List View called LV_Options
private void LV_Options_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListView lv1 = sender as ListView;
if (lv1 == null)
return;
MyTBL wrd = lv1.SelectedItem as MyTBL;
if (wrd == null)
return;
TextBlock tb = lv1.FindName("TB_AMean1") as TextBlock;
tb.FontSize = 17; // here I got debug error (it not worked !!!!!!!)
var item = LV_Options.Items.ElementAt(3); // this seems not work also !!!!
item.BackColor = Color.LightSteelBlue;
}
As you can see above, I tried to reach a specific item by LV_Options.Items.ElementAt(3) but it doesn't work! I also tried to reach the TextBlock from the selected List view item, but also not worked !
(Updated)
XAML code :
<!-- Title Panel -->
<StackPanel Grid.Row="0" Margin="19,0,0,0">
<TextBlock Name="TB_Rslt" Text="Here result of your answer" Style="{ThemeResource TitleTextBlockStyle}" Margin="0,12,0,0"/>
<TextBlock Text="page title" Margin="0,-6.5,0,26.5" Style="{ThemeResource HeaderTextBlockStyle}" CharacterSpacing="{ThemeResource PivotHeaderItemCharacterSpacing}"/>
</StackPanel>
<!--TODO: Content should be placed within the following grid-->
<Grid Grid.Row="1" x:Name="ContentRoot" Margin="19,10,19,15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="TB_Question" Text="Choose Answer " Margin="0,0,25,0" HorizontalAlignment="Right" FontWeight="Bold" FontSize="22" FontFamily="Verdana" RenderTransformOrigin="0.5,0.5" />
<TextBlock Name="TB_EnWord" Text="" Margin="90,0,15,0" HorizontalAlignment="Left" FontWeight="Bold" FontSize="22" FontFamily="Verdana" RenderTransformOrigin="0.5,0.5" TextAlignment="Right" />
<StackPanel Grid.Row="1" Margin="5,22,0,0">
<ListView Name="LV_Options" SelectionChanged="LV_Options_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="6">
<StackPanel VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Name="TB_AMean1" Text="{Binding AMean1}" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
<Button Name="Btn_Answer" Content="Ansewr" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Bottom" Click="Btn_Answer_Click"/>
My application is a quiz application that offer 4 choices/options as answers for each question, and when user select a true answer, I want to highlight the true answer(true choice) by make its background to green, and if the user selected wrong answer/option I want to make the background of that answer (a specific List View item) with red.
Any help please ?
You're not going to be able to access an element inside a data template like that. Instead, leverage the binding to a view model to set the color and other view-related properties. First, create a wrapper view model for your data class:
public class MyTBLViewModel : INotifyPropertyChanged
{
public MyTBL Entity
{
get { return _entity; }
}
private readonly MyTBL _entity;
public Brush Highlight
{
get { return _brush; }
set
{
_brush = value;
RaisePropertyChanged("Highlight");
}
}
private Brush _highlight;
public double ItemFontSize
{
get { return _itemFontSize; }
set
{
_itemFontSize = value;
RaisePropertyChanged("ItemFontSize");
}
}
private Brush _itemFontSize;
public MyTBLViewModel(MyTBL entity)
{
_entity = entity;
_highlight = new SolidColorBrush(Colors.Transparent);
_itemFontSize = 12;
}
public event PropertyChangedEventArgs PropertyChanged;
protected void RaisePropertyChanged(string propName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propName));
}
}
Use this as your ItemsSource:
List<MyTBLViewModel> t_list = db1.GetTable("SELECT * FROM MyTBL LIMIT 4 ORDER BY RANDOM() ;")
.AsEnumerable().Select(entity => new MyTBLViewModel(entity)).ToList();
Now in your view, bind the view elements to "Highlight" and "ItemFontSize", and to any other properties you like:
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="6" Background="{Binding Highlight}">
<StackPanel VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Name="TB_AMean1" Text="{Binding Entity.AMean1}" TextWrapping="Wrap"
FontSize="{Binding ItemFontSize}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
Finally, you can get the data item from the SelectionChangedEventArgs -- use it to update your view-related properties:
private void LV_Options_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (var item in e.AddedItems.OfType<MyTBLViewModel>())
{
item.Highlight = new SolidColorBrush(Color.LightSteelBlue);
item.ItemFontSize = 17;
}
foreach (var item in e.RemovedItems.OfType<MyTBLViewModel>())
{
item.Highlight = new SolidColorBrush(Colors.Transparent);
item.ItemFontSize = 12;
}
}
var item = LV_Options.Items.ElementAt(3);
This line is incorrect. It will not return you a TextBlock. I don't know what a .BackColor is, and it should not compile. The Items property in a ListView will return you a list of ListViewItems. If you want to access the inside element from a ListViewItem, you'll need to access the ContentTemplateRoot property.
Do not use var ever. It lets you assume that you know the type, whereas if you explicitly typed the declaration you would realize you're doing it wrong.
MyTBL wrd = lv1.SelectedItem as MyTBL;
if (wrd == null)
return;
TextBlock tb = lv1.FindName("TB_AMean1") as TextBlock;
What is a MyTBL type? FindName is only available to framework DependencyObjects so I'm assuming it's a user control? You have to provide a lot more code to show us what you're doing and what you're setting the ListView's ItemsSource and ItemTemplate with and what these errors are and how you have 2 breaking debug errors at once and what the error messages are.
Comprehending runtime error messages is a huge part of being a good developer.
My GridView items having the size of it's first item size. How do i can change this behaviour ?
How to display GridView items with variable Width as per the content ?
I want to show the first one but i am getting second one. Any suggestion to do that?
Check Windows 8 GridView and Variable-Sized Items and Different Sized Tile Items in WinRT GridView and also check Variable Sized Grid Template Hope this help
You can create such view of GridView by setting ItemsPanel to WrapPanel, you can get WrapPanel on Jerry Nixon's blog. Here's the code.
XAML
<GridView x:Name="gv">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<local:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Height="140" Width="{Binding MyWidth}">
<Grid.Background>
<SolidColorBrush Color="{Binding MyColor}" />
</Grid.Background>
<TextBlock FontSize="20" VerticalAlignment="Bottom" Margin="10,0,0,10">
<Run Text="{Binding MyWidth}" />
</TextBlock>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
C#
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var list = new List<ViewModel>()
{
new ViewModel(110, Colors.LawnGreen),
new ViewModel(50, Colors.DarkBlue),
new ViewModel(130, Colors.Firebrick),
new ViewModel(60, Colors.RosyBrown),
new ViewModel(100, Colors.IndianRed),
new ViewModel(210, Colors.BurlyWood),
new ViewModel(150, Colors.Turquoise)
};
gv.ItemsSource = list;
}
public class ViewModel
{
public double MyWidth { get; set; }
public Color MyColor { get; set; }
public ViewModel(double _MyWidth, Color _MyColor)
{
MyWidth = _MyWidth;
MyColor = _MyColor;
}
}
Here is my solution.
//variable sized grid view
public class VariableSizedGridView : GridView
{
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
try
{
dynamic gridItem = item;
var typeItem = item as CommonType;
if (typeItem != null)
{
var heightPecentage = (300.0 / typeItem.WbmImage.PixelHeight);
var itemWidth = typeItem.WbmImage.PixelWidth * heightPecentage;
var columnSpan = Convert.ToInt32(itemWidth / 10.0);
if (gridItem != null)
{
element.SetValue(VariableSizedWrapGrid.ItemWidthProperty, itemWidth);
element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, columnSpan);
element.SetValue(VariableSizedWrapGrid.RowSpanProperty, 1);
}
}
}
catch
{
element.SetValue(VariableSizedWrapGrid.ItemWidthProperty, 100);
element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, 1);
element.SetValue(VariableSizedWrapGrid.RowSpanProperty, 1);
}
finally
{
base.PrepareContainerForItemOverride(element, item);
}
}
//Collection View source
<CollectionViewSource x:Name="collectionViewSource"
Source="{Binding ImageList,Mode=TwoWay}"
IsSourceGrouped="False"
ItemsPath="Items" />
//variable sized Grid view xaml
<controls:VariableSizedGridView x:Name="ImageGridView"
AutomationProperties.AutomationId="ImageGridView"
ItemsSource="{Binding Source={StaticResource collectionViewSource}}"
IsItemClickEnabled="True"
TabIndex="1" >
<controls:VariableSizedGridView.ItemTemplate>
<DataTemplate>
<Grid Height="300" >
<Image Stretch="Uniform" Source="{Binding WbmImage}" />
</Grid>
</DataTemplate>
</controls:VariableSizedGridView.ItemTemplate>
<controls:VariableSizedGridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid ItemWidth="10" ItemHeight="300" Orientation="Vertical"/>
</ItemsPanelTemplate>
</controls:VariableSizedGridView.ItemsPanel>
</controls:VariableSizedGridView>