Windows StoreApp XAML: Changing ItemTemplate in GridView based on Data type - xaml

I am working on developing Windows Store App using C#/XAML. I have experience primarily in iOS and to some extent Android app development, but not yet comfortable with C#/XAML world.
Here is my issue in GridView based page (Based on the nice template VS2012 generates).
I have a gridview and its collection is bound to a data retrieved from network and it works fine.
But I want to change the grid item depending on the data.
For example: I have files and folders that I would like to show using different grid view items.
My Question: How would I use a different DataTemplate for the ItemTemplate depending on the data? For example, for "Folders", I will have only one textblock which is vertically centered and for File, I will have the 2 textblocks and visually different.
Am I going the right path or should I be doing completely different?
The XAML Portion is
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="3"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource FileEntriesTemplate}"
ItemClick="ItemView_ItemClick"
IsItemClickEnabled="True"
SelectionMode="None"
IsSwipeEnabled="false">
The Template is
<DataTemplate x:Key="FileEntriesTemplate">
<Grid HorizontalAlignment="Left" Width="400" Height="80" Background="Beige">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding Image}" Stretch="Uniform" Grid.Column="0" Margin="10,0,0,0" AutomationProperties.Name="{Binding Title}"/>
<StackPanel Orientation="Vertical" Grid.Column="1" Background="Transparent">
<TextBlock Text="{Binding Title}" Foreground="Black" Style="{StaticResource LargeTitleTextStyle}" Margin="20,20,10,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="gray" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="20,10,0,30"/>
</StackPanel>
</Grid>

GridView exposes this through the ItemTemplateSelector property which is a class you can create that inherits from DataTemplateSelector. An example would be that I have a GridView that has Issues and Repositories bound to it and want to use different data templates for each.
My data template selector looks like:
public class IssueSummaryTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return item is IssueGroupViewModel ? IssueTemplate : RepositoryTemplate;
}
public DataTemplate RepositoryTemplate
{
get;
set;
}
public DataTemplate IssueTemplate
{
get;
set;
}
}
I then declare the selector as a Resource in xaml assigning the two templates I want to use for Repository and Issues.
<selectors:IssueSummaryTemplateSelector x:Key="IssueSummarySelector"
IssueTemplate="{StaticResource IssueGridZoomedOutTemplate}"
RepositoryTemplate="{StaticResource IssueGridRepositoryZoomedOutTemplate}"/>
You can then use it on your GridView.
<GridView ItemTemplateSelector="{StaticResource IssueSummarySelector}" />

Related

Dynamic ListView display based on Itemsource {Binding} to ObservableCollection<"this can change and dictates listview style"?>

Summary of the Question: What is the correct way to manipulate the same, single ObservableCollection in a xaml page's viewmodel (binded to the ListView of the page ), at runtime in order to show different sets of data, each variation of data providing its own ListView-Style via a StyleSelector?
Description:
I have a UWP xaml page with a single ListView, I want this listview to display all different possible data sets the user might want to see. e.g: A dataset could be between one to 15 columns of data, all with headers. The ListView's ItemSource will use binding to an ObservableCollection to populate it. The ObservableCollection can be populated manually or with one of many SQL sourced DataTable's.
<ListView x:Name="UserPageListView"
ItemsSource="{Binding MainListData, Mode=TwoWay}"
Grid.Column="1"
Width="auto"
Background="Gray"
ItemContainerStyleSelector="{StaticResource UserPage_StyleSelector}">
</ListView>
I have tried binding the ItemContainerStyleSelector to provide a xaml ListView Style (which is stored in a ResourceDictionary), based on the data type of the ObservableCollection, or at least that was the idea. I don't know whether the ObservableCollection's data type should be generic or a defined class per data set to view. The latter makes sense, since a StyleSelector would need it for logic to provide the relevant Style. I used StyleSelector instead of DataTemplateSelector since I want the Selector to include HeaderTemplate as well as ItemTemplate(headers of columns change with the different data sets):
public class UserPage_StyleSelector:StyleSelector
{
public Style WatchlistStyle { get; set; }
public Style UserDetailStyle { get; set; }
protected override Style SelectStyleCore(object item, DependencyObject container)
{
if (item is WatchlistData)
return WatchlistStyle;
if (item is UserDetailData)
return UserDetailStyle;
return base.SelectStyleCore(item, container);
}
}
Style example in ResourceDictionary:
<Style TargetType="ListView"
x:Key="UserDetail_ListView"
x:Name="UserDetail_ListView">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Grid Padding="12"
Background="{ThemeResource SystemBaseLowColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<TextBlock Text="UserDetails"
Style="{ThemeResource CaptionTextBlockStyle}"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding Details}"
FontSize="12"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
StyleSelector defined in the xaml page:
<Page.Resources>
<viewModels:UserPage_StyleSelector x:Key="UserPage_StyleSelector"
WatchlistStyle="{StaticResource WatchList_ListView}"
UserDetailStyle="{StaticResource UserDetail_ListView}"/>
</Page.Resources>
The ResourceDictionary is defined in app.xaml.cs. Have I complicated this endeavour far too much by using the wrong approach?
ItemContainerStyle target type is ListViewItem, so you can't make ListView style in ItemContainerStyleSelector.
Derive from your requirement (headers of columns change with the different data sets), you need make GroupStyleSelector and ItemTemplateSelector for different header and columns.
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock
Margin="5"
FontSize="25"
Foreground="Gray"
Text="{Binding Name}"
/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
For more detail please refer this document.

Xamarin Forms Rowspan in CollectionView

I have a problem.
I created this CollectionView with a few dummy trades, that looks like this right now:
Now this is almost like I want it, except for 1 thing: I want the last column to get a rowspan over both the rows, like this:
Now if this was a regular Grid, I could do it with Grid.RowSpawn, but it is in a CollectionView, because I can have a lot of trades. The downside of the CollectionView is that each row is a different Grid, so they are actually not connected! Here is my code right now:
<CollectionView ItemsSource="{Binding agentOrderList}" Margin="0" HeightRequest="450">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0">
<StackLayout Orientation="Vertical">
<StackLayout HorizontalOptions="FillAndExpand" HeightRequest="1" BackgroundColor="White"/>
<Grid RowSpacing="0" Margin="5,0,5,0">
<Grid.RowDefinitions>
<RowDefinition Height="21" />
<RowDefinition Height="21" />
<RowDefinition Height="4" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65" />
<ColumnDefinition Width="95" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="75" />
<ColumnDefinition Width="82" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Text="{Binding Date}" FontAttributes="Bold" TextColor="#00D8FF" FontSize="18" VerticalOptions="CenterAndExpand"/>
<Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Text="{Binding Action}" TextColor="White" FontSize="18" VerticalOptions="CenterAndExpand"/>
<Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Text="{Binding Coin}" TextColor="White" FontSize="18" VerticalOptions="CenterAndExpand"/>
<Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="3" Text="{Binding Price}" TextColor="White" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End"/>
<Label Grid.Row="0" Grid.Column="4" Text="{Binding ProfitUSDT}" TextColor="{Binding ProfitColor}" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End"/>
<Label Grid.Row="1" Grid.Column="4" Text="{Binding ProfitPerc}" TextColor="{Binding ProfitColor}" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End"/>
</Grid>
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Now what is the best way to achieve this? Do I need to make a different view?
Please let me know!
You can't have data cross over between cells in a ListView, so I think you will need to make each list item have a two row grid, so then you can have the last column span two rows.
However, I am confused. Your XAML code does not seem to match the screen shot of one cell. Your XAML code only seems to assign 5 columns, but I see 6 in your screen shots?
IN any case, you are correct, you will need to use one grid to display the Buy and Sell data so that that last column can span 2 rows.
UPDATE: Based on comments below, it seems a DataTemplateSelector may be required here. See: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/selector
Partial extract from above link:
A data template selector enables scenarios such as a ListView binding
to a collection of objects, where the appearance of each object in the
ListView can be chosen at runtime by the data template selector
returning a particular DataTemplate.
Creating a DataTemplateSelector A data template selector is
implemented by creating a class that inherits from
DataTemplateSelector. The OnSelectTemplate method is then overridden
to return a particular DataTemplate, as shown in the following code
example:
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate ValidTemplate { get; set; }
public DataTemplate InvalidTemplate { get; set; }
protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
{
return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;
}
}
The OnSelectTemplate method returns the
appropriate template based on the value of the DateOfBirth property.
The template to return is the value of the ValidTemplate property or
the InvalidTemplate property, which are set when consuming the
PersonDataTemplateSelector.
An instance of the data template selector class can then be assigned
to Xamarin.Forms control properties such as ListView.ItemTemplate. For
a list of valid properties, see Creating a DataTemplate.
Limitations
DataTemplateSelector instances have the following limitations:
The DataTemplateSelector subclass must always return the same template
for the same data if queried multiple times.
The DataTemplateSelector subclass must not return another DataTemplateSelector subclass.
The DataTemplateSelector subclass must not return new instances of a
DataTemplate on each call. Instead, the same instance must be
returned. Failure to do so will create a memory leak and will disable
virtualization.
On Android, there can be no more than 20 different
data templates per ListView.
Consuming a DataTemplateSelector in XAML
In XAML, the PersonDataTemplateSelector can be instantiated by
declaring it as a resource, as shown in the following code example:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Selector;assembly=Selector" x:Class="Selector.HomePage">
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="validPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="invalidPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<local:PersonDataTemplateSelector x:Key="personDataTemplateSelector"
ValidTemplate="{StaticResource validPersonTemplate}"
InvalidTemplate="{StaticResource invalidPersonTemplate}" />
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
This page level ResourceDictionary defines two DataTemplate instances and a
PersonDataTemplateSelector instance. The PersonDataTemplateSelector
instance sets its ValidTemplate and InvalidTemplate properties to the
appropriate DataTemplate instances by using the StaticResource markup
extension. Note that while the resources are defined in the page's
ResourceDictionary, they could also be defined at the control level or
application level.
The PersonDataTemplateSelector instance is consumed by assigning it to
the ListView.ItemTemplate property, as shown in the following code
example:
<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" />
At runtime, the ListView calls the
PersonDataTemplateSelector.OnSelectTemplate method for each of the
items in the underlying collection, with the call passing the data
object as the item parameter. The DataTemplate that is returned by the
method is then applied to that object.

XAML: Binding scrollviewer with 2 sources

Trying to learn xaml designing. I got this picture from internet and use it as a model to practice. There is a problem: When I click one of day buttons, a scrollviewer with a list of day tasks appears. Each task has a list of hours in day, from start time to end time. I don't know whether they are from one source or 2 source (one describes day task and the other one is a list of hours of this task).
I tried with this
public async void ShowTasks()
{
ObservableCollection<DayTask> Data = await App.DataSource.GetData();
DateListBox.ItemsSource = Data;
DayTask daytask = Data.Where(x => x.Day.Date == App.Day.Date).FirstOrDefault();
TasksListView.ItemsSource = daytask.Tasks;
List<HoursModel> HoursList = new List<HoursModel>();
foreach (var simpletask in daytask.Tasks)
{
HoursList.Add(new HoursModel(simpletask.StartTimeHour, simpletask.EndTimeHour));
}
HoursListView.ItemSource = HoursList;
}
This is my xaml code:
<ScrollViewer Height="730" Width="300" >
<ListView
x:Name="TasksListView" Height="730" Width="300"
HorizontalAlignment="Right">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<ListView
Grid.Column="0"
x:Name="HoursListView">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock
x:Name="ShowedHours"
Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Column="1">
<Rectangle
Fill="Pink"
Height="75"
Width="150"
Margin="60,20,0,0"/>
<TextBlock
Text="{Binding Description}"
FontSize="17"
TextWrapping="Wrap"
Margin="80,20,0,0"/>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
I got an error with HoursListView.ItemSource = HoursList;. The detail of this error is
The name 'HoursListView' does not exist in the current context. Does anyone have any suggestions how I can do this ?
You can't access control in DataTemplate directly by it's name. That makes sense because DataTemplate in this case is generated repeatedly for each item within TasksListView.
According to XAML markup posted, you want to have different HoursList for each DayTask. That can be achieved by adding an HoursList property in DayTask class. I'd suggest to use ObservableCollection instead of List because the former has built-in feature to notify bound UI to refresh whenever item added to or removed from collection :
public class DayTask
{
public ObservableCollection<HoursModel> HoursList { get; set; }
.....
}
Then bind HoursListView's ItemsSource to above property :
.....
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<ListView
Grid.Column="0"
ItemsSource="{Binding HoursList}"
x:Name="HoursListView">
.....
</ListView>
</Grid>
</DataTemplate>
.....
Don't forget to populate all HoursList properties before setting DateListBox.ItemsSource.

How to bind to a list of images

I have changed my code to this:
the view:
<phone:Panorama.ItemTemplate>
<DataTemplate>
<ScrollViewer Width="800" HorizontalContentAlignment="Left" Margin="0,50,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox x:Name="list_of_images" ItemsSource="{Binding ImagesUrls}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Width="300" Height="300" Source="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>
<TextBlock Text="{Binding Title}"
Grid.Row="1"
Loaded="TextBlock_Loaded_1"
Margin="50,0,0,0"
FontSize="23"
TextWrapping="Wrap"
Width="360"
HorizontalAlignment="Left"
Foreground="Black"/>
<TextBox Text="{Binding ContactEmail}"
Grid.Row="2"
BorderBrush="Black"
Width="340"
HorizontalAlignment="Left"
BorderThickness="1"
Margin="40,0,0,0"
Foreground="Black" />
<TextBlock Text="{Binding Body}"
Grid.Row="3"
TextWrapping="Wrap"
Foreground="Black"
Margin="50,5,0,0"
Width="360"
HorizontalAlignment="Left"
FontSize="20" />
</Grid>
and I build a new object with different properties, with one of the properties being a list of strings which represents the imageurls, but I cannot get the images to show?
I have attached screenshots, what in my xaml must I change so that I can display the images, cause at the moment it doesn't show any images but it shows all the other details
code for populating collection:
ObservableCollection<ClassifiedAds> klasifiseerd_source = new ObservableCollection<ClassifiedAds>();
ImagesClassifieds new_Classifieds = new ImagesClassifieds();
ObservableCollection<string> gallery_images = new ObservableCollection<string>();
new_Classifieds.Title = klasifiseerd_source[0].Title;
new_Classifieds.ContactEmail = klasifiseerd_source[0].ContactEmail;
new_Classifieds.Body = klasifiseerd_source[0].Body;
foreach (var item in klasifiseerd_source[0].Gallery.Images)
{
var deserialized = JsonConvert.DeserializeObject<GalleryImages>(item.ToString());
gallery_images.Add(deserialized.ImageUrl);
//new_Classifieds.ImageUrls.Add(deserialized.ImageUrl);
}
new_Classifieds.ImageUrls = gallery_images;
// classifiedPanorama.ItemsSource = new_list;
new_Classifieds_list.Add(new_Classifieds);
classifiedPanorama.ItemsSource = new_Classifieds_list;
public class ImagesClassifieds
{
public string Title { get; set; }
public string ContactEmail { get; set; }
public string Body { get; set; }
public ObservableCollection<string> ImageUrls { get; set; }
}
here is the imageurl format, this works (in another par tof my app I simply bind to 1 image in this format and it works perfectly)
Depending on whether you want to just display a list of images or if you also want to be able to select them, you may either choose an ItemsControl or a ListBox. In both case you have to define a DataTemplate that controls how each item is displayed.
<ItemsControl ItemsSource="{Binding Images}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
or
<ListBox ItemsSource="{Binding Images}">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Then you should think about how you define your item class. Just in case you want to be able to dynamically add or remove images from the list and let the UI be automatically updated, you should use an ObservableCollection as container type. As there is a built-in type conversion from string to ImageSource (the type of the Image control's Source property), you may simply use an ObservableCollection<string>.
public class Gal
{
public ObservableCollection<string> Images { get; set; }
}
You may create an instance of that class like so:
var gallery = new Gal();
gallery.Images = new ObservableCollection<string>(
Directory.EnumerateFiles(#"C:\Users\Public\Pictures\Sample Pictures", "*.jpg"));
Now you may directly bind to that instance by simply setting the DataContext of your Window (or wherever the image list should be shown) to this instance:
DataContext = gallery;
Note the binding declaration in the ItemsControl or ListBox above was {Binding Images}. If you really have to have a property Gallery (which I assume is in MainWindow) and bind like {Binding Gallery.Images} you may set the DataContext like this:
DataContext = this;
so I basically created a loaded event on the listbox and added this code
private void list_of_images_Loaded_1(object sender, RoutedEventArgs e)
{
ListBox lst = (ListBox)sender;
lst.ItemsSource = new_Classifieds_list[0].ImageUrls;
}
which binds the itemssource of the listbox to the list of imageurls. since I cannot access the listbox from codebehind due to it being inside the panorama's itemstemplate

Color Binding Not Working for Data Templates in Win8 App

I'm currently trying to add some sort of a Color Theme feature to a Win8 App I'm working at... I've though of making a binding from a vm, and everything works fine for static UI elements. But, I'm adding some notes (my model) into a DB, and they also appear on the screen into a GridView.
But in the declared DataTemplate for the GridView ItemTemplate, the Color Binding will not work at all...
My template looks like this :
<Grid Grid.Row="3" HorizontalAlignment="Left" Width="200" Height="200">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="60"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="Lavender" Opacity="50"/>
<ScrollViewer Grid.Row="0">
<TextBlock Grid.Row="0" Text="{Binding Content}" Foreground="DodgerBlue" />
</ScrollViewer>
<Border Grid.Row="1" Background="DodgerBlue" Opacity="70"/>
<ScrollViewer Grid.Row="1">
<TextBlock Grid.Row="1" Text="{Binding Subject}" Foreground="LightBlue" />
</ScrollViewer>
<Border Grid.Row="2" Background="DodgerBlue" Opacity="70"/>
<TextBlock Grid.Row="2" Text="{Binding Importance}" Foreground="Black" FontSize="{StaticResource ComboBoxArrowThemeFontSize}" />
</Grid>
What I tried was simply instead of Foreground="DodgerBlue" to Foreground="{Binding ColorTheme}" but it had no effect, the SolidColorBrush was not acquired from vm....
Is there any workaround for this?
Many thanks in advance.
Altough I didn't really find out the actual explanation on why the below works (and I hope someone more experience, maybe could explain me), this post, seemed to have worked for me.
Not very sure, but was a matter of DataContext, so instead of trying a binding like this : Foreground={Binding ColorTheme}, I changed to this : Foreground={Binding DataContext.ColorTheme, ElementName=MyGridViewName}".
Color binding (or better: brush binding) should work just fine - in GridView.ItemTemplate scenario and elsewhere.
You haven't given enough info to pinpoint why it doesn't work in your case, but here is a small sample I've just tried out:
GridView to put in your page:
<GridView Width="600" Height="200" ItemsSource="{Binding GridItems}"
x:Name="GridViewName">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Width="50" Height="50"
Foreground="{Binding Color}" Text="{Binding Text}" />
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
View model class bound as DataContext for your page:
public class ViewModel
{
public ViewModel()
{
GridItems = new List<GridItem>
{
new GridItem {Text = "First", Color = new SolidColorBrush(Colors.White)},
new GridItem {Text = "Second", Color = new SolidColorBrush(Colors.Yellow)},
new GridItem {Text = "Third", Color = new SolidColorBrush(Colors.Green)},
new GridItem {Text = "Fourth", Color = new SolidColorBrush(Colors.Red)},
};
}
}
GridItem class:
public class GridItem
{
public string Text { get; set; }
public Brush Color { get; set; }
}
The result:
EDIT:
I need to point out that inside data template DataContext is set to the current item of the bound collection (GridItems in my case) not to the page DataContext (ViewModel in my case).
This means that by setting {Binding Color} to a control property you're binding to GridItem.Color not to ViewModel.Color. To make the latter work you first need to access the parent DataContext using the ElementName syntax as you already suggested in your own answer: {Binding DataContext.ColorTheme, ElementName=GridViewName} - this binds to a named element on the page and allows you to access its properties, DataContext being ViewModel in this case.