I successfully coded an XAML Gridview to show list of items.
However, I want to add an [+(ADD ITEM)] button at the end of the Gridview.
The ADD button has should have a custom template (at least a default button) which is different from the content item.
My XAML source is below:
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
ItemsSource="{Binding Source={StaticResource DataSource}}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Subject}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource BaseTextBlockStyle}" Height="60" Margin="15,0,15,0" FontWeight="SemiBold"/>
<TextBlock Text="{Binding TargetDate}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource BaseTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10" FontSize="12"/>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<!--
Something like that..
<Button Content="+" x:Name="btnAdd" />
-->
</GridView>
And, how can I add a ADD button(grid item) to XAML? thanks
You can achieve that by using a DataTemplateSelector, basically what you need to do is :
define another class that will represent the GridView "addItem"
public class GridItem
{
public String Subject { get; set; }
public String TargetDate { get; set; }
}
public class AddGridItem : GridItem
{
public bool IsGridItem { get; set; }
}
Make sure that your GridView's ItemSource collection has always an AddGridItem in it
private ObservableCollection<GridItem> _gridItems =new ObservableCollection<GridItem>()
{
new GridItem()
{
Subject = "Subject1",
TargetDate = "TargetDate"
},new GridItem()
{
Subject = "Subject2",
TargetDate = "TargetDate"
},new GridItem()
{
Subject = "Subject3",
TargetDate = "TargetDate"
},new AddGridItem()
{
IsGridItem = true
}
};
public ObservableCollection<GridItem> GridItems
{
get
{
return _gridItems;
}
set
{
if (_gridItems == value)
{
return;
}
_gridItems = value;
}
}
Create a DataTemplateSelector class that will return the appropriate DataTemplate based on the Item type
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate RegularTemplate { get; set; }
public DataTemplate AddTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item,
DependencyObject container)
{
if (item is AddGridItem)
return AddTemplate;
if (item is GridItem)
return RegularTemplate;
return base.SelectTemplateCore(item, container);
}
}
Define your dataTempaltes and a DataTemplateSelector as staticresources to use them in your GridView
<Page.Resources>
<DataTemplate x:Key="RegularTemplate">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border BorderThickness="3" BorderBrush="White">
<StackPanel VerticalAlignment="Bottom" Background="LightSkyBlue">
<TextBlock Text="{Binding Subject}" Style="{StaticResource BaseTextBlockStyle}" Height="60" Margin="15,0,15,0" FontWeight="SemiBold"/>
<TextBlock Text="{Binding TargetDate}" Style="{StaticResource BaseTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10" FontSize="12"/>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AddItemTemplate">
<Border BorderThickness="3" BorderBrush="White" Background="DodgerBlue">
<FontIcon Glyph="" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/>
</Border>
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
RegularTemplate="{StaticResource RegularTemplate}"
AddTemplate="{StaticResource AddItemTemplate}">
</local:MyDataTemplateSelector>
</Page.Resources>
<Grid>
<GridView ItemsSource="{Binding GridItems}" ItemTemplateSelector="{StaticResource MyDataTemplateSelector}">
</GridView>
</Grid>
Related
When using a SemanticZoom control, is there a way to update the ObservableCollection in the ViewModel after a table change? After making changes to the table in SQLite, within the same page (categories.xaml.cs), the SemanticZoom control does not update. Reloading the page from menu navigation does reload the page with the correct data. If the control just took an ObservableCollection as it's items source, the ObservableCollection could just be refreshed. Using a ViewModel was the only code example I could find for the SemanticZoom control. Thanks in advance!
categories.xaml
<Page.DataContext>
<vm:CategoriesViewModel></vm:CategoriesViewModel>
</Page.DataContext>
<Page.Resources>
<CollectionViewSource x:Name="Collection" IsSourceGrouped="true" ItemsPath="Items" Source="{Binding CategoryGroups}" />
</Page.Resources>
<SemanticZoom Name="szCategories" ScrollViewer.ZoomMode="Enabled">
<SemanticZoom.ZoomedOutView>
<GridView ScrollViewer.IsHorizontalScrollChainingEnabled="False">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Group.Name }" Foreground="Gray" Margin="5" FontSize="25" />
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</SemanticZoom.ZoomedOutView>
<SemanticZoom.ZoomedInView>
<ListView Name="lvCategories" ItemsSource="{Binding Source={StaticResource Collection}}" Tapped="lvCategories_Tapped">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:Category">
<StackPanel>
<TextBlock Text="{Binding Title}" Margin="5" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text='{Binding Name}' Foreground="Gray" FontSize="25" Margin="5,5,5,0" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</SemanticZoom.ZoomedInView>
</SemanticZoom>
categories.xaml.cs
public Categories()
{
this.InitializeComponent();
var collectionGroups = Collection.View.CollectionGroups;
((ListViewBase)this.szCategories.ZoomedOutView).ItemsSource = collectionGroups;
}
CategoriesViewModel.cs
internal class CategoriesViewModel : BindableBase
{
public CategoriesViewModel()
{
CategoryGroups = new ObservableCollection<CategoryDataGroup>(CategoryDataGenerator.GetGroupedData());
}
private ObservableCollection<CategoryDataGroup> _groups;
public ObservableCollection<CategoryDataGroup> CategoryGroups
{
get { return _groups; }
set { SetProperty(ref _groups, value); }
}
}
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(string propertyName)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
SymanticZoom.cs
internal class CategoryDataGroup
{
public string Name { get; set; }
public List<CategoryData> Items { get; set; }
}
internal class CategoryData
{
public CategoryData(string grp, string title)
{
Grp = grp;
Title = title;
}
public string Grp { get; private set; }
public string Title { get; private set; }
}
internal class CategoryDataGenerator
{
private static List<CategoryData> _data;
public static List<CategoryDataGroup> GetGroupedData()
{
if (_data != null)
_data.Clear();
GenerateData();
return _data.GroupBy(d => d.Grp[0],
(key, items) => new CategoryDataGroup() { Name = key.ToString(), Items = items.ToList() }).ToList();
}
private static void GenerateData()
{
ObservableCollection<Category> ocCategories = new ObservableCollection<Category>();
SQLiteManager.Categories.Select(ocCategories);
_data = new List<CategoryData>();
foreach (var temp in ocCategories)
{
_data.Add(new CategoryData(temp.Name.Substring(0,1), temp.Name));
}
}
}
The zoomed-in view and zoomed-out view should be synchronized, so if a user selects a group in the zoomed-out view, the details of that same group are shown in the zoomed-in view. You can use a CollectionViewSource or add code to synchronize the views.
For more info, see Semantic zoom.
We can use CollectionViewSource control in our page, it provides a data source that adds grouping and current-item support to collection classes. Then we can bind the GridView.ItemSource and ListView.ItemSource to the CollectionViewSource. When we set new data to the CollectionViewSource, the GridView in SemanticZoom.ZoomedOutView and ListView in SemanticZoom.ZoomedInView will be updated.
xmlns:wuxdata="using:Windows.UI.Xaml.Data">
<Page.Resources>
<CollectionViewSource x:Name="ContactsCVS" IsSourceGrouped="True" />
<DataTemplate x:Key="ZoomedInTemplate" x:DataType="data:Contact">
<StackPanel Margin="20,0,0,0">
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Position}" TextWrapping="Wrap" HorizontalAlignment="Left" Width="300" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ZoomedInGroupHeaderTemplate" x:DataType="data:GroupInfoList">
<TextBlock Text="{x:Bind Key}"/>
</DataTemplate>
<DataTemplate x:Key="ZoomedOutTemplate" x:DataType="wuxdata:ICollectionViewGroup">
<TextBlock Text="{x:Bind Group.(data:GroupInfoList.Key)}" TextWrapping="Wrap"/>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<SemanticZoom x:Name="Control1" Height="500">
<SemanticZoom.ZoomedInView>
<GridView ItemsSource="{x:Bind ContactsCVS.View,Mode=OneWay}" ScrollViewer.IsHorizontalScrollChainingEnabled="False" SelectionMode="None"
ItemTemplate="{StaticResource ZoomedInTemplate}">
<GridView.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource ZoomedInGroupHeaderTemplate}" />
</GridView.GroupStyle>
</GridView>
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
<ListView ItemsSource="{x:Bind ContactsCVS.View.CollectionGroups}" SelectionMode="None" ItemTemplate="{StaticResource ZoomedOutTemplate}" />
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
</StackPanel>
</Grid>
I have a button with the image and textblock.
Buttons are created dynamically based on the values from the database.
Now for a particular value text is present and no image is there I want to show that text in the center of the button (horizontally and vertically), but it is not working.
Please find the xaml below:
<ItemsControl ItemsSource="{Binding CategoriesList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="100" Margin="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border CornerRadius="10" Background="Maroon">
<StackPanel Orientation="Vertical">
<Image Source="{Binding CategoryImagePath}" Height="50"></Image>
<TextBlock Text="{Binding CategoryName}" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
If no image is available I want to show only the text on the button but it should be centered.
If there is Image then I make the Image and text both displayed but when the Image is not available the text is getting displayed but it is not in the center It moves to the top portion of the button.
You can use a DataTemplateSelector to select different templates depending on whether you have an image. Such a selector might look like this:
public sealed class ButtonTemplateSelector : DataTemplateSelector
{
/// <summary>
/// Gets or sets the <see cref="DataTemplate"/> to use when we have an image.
/// The value is set in XAML.
/// </summary>
public DataTemplate ImageTemplate { get; set; }
/// <summary>
/// Gets or sets the <see cref="DataTemplate"/> to use when we don't have an image.
/// The value is set in XAML.
/// </summary>
public DataTemplate NoImageTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Category category = item as Category;
if (category != null)
{
return category.CategoryImagePath == null ? NoImageTemplate : ImageTemplate;
}
return base.SelectTemplate(item, container);
}
}
I'm assuming a model object something like this:
public class Category
{
public string CategoryImagePath { get; set; }
public string CategoryName { get; set; }
}
Create and initialize a ButtonTemplateSelector resource in your XAML, then reference it from your ItemsControl:
<Window
x:Class="WPF.MainWindow"
x:Name="self"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:WPF"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<Grid.Resources>
<wpf:ButtonTemplateSelector x:Key="ButtonTemplateSelector">
<wpf:ButtonTemplateSelector.ImageTemplate>
<DataTemplate DataType="wpf:Category">
<Button
Width="100"
Margin="5"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border CornerRadius="10" Background="Maroon">
<StackPanel Orientation="Vertical">
<Image
Source="{Binding CategoryImagePath}"
Height="50" />
<TextBlock
Foreground="White"
Text="{Binding CategoryName}"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</wpf:ButtonTemplateSelector.ImageTemplate>
<wpf:ButtonTemplateSelector.NoImageTemplate>
<DataTemplate DataType="wpf:Category">
<Button
Width="100"
Margin="5"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border
CornerRadius="10"
Background="Maroon"
Height="70">
<TextBlock
Foreground="White"
Text="{Binding CategoryName}"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</wpf:ButtonTemplateSelector.NoImageTemplate>
</wpf:ButtonTemplateSelector>
</Grid.Resources>
<ItemsControl
DataContext="{Binding ElementName=self}"
ItemsSource="{Binding CategoriesList}"
ItemTemplateSelector="{StaticResource ButtonTemplateSelector}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Window>
For completeness, the code-behind for the window:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
public IEnumerable<Category> CategoriesList { get; } = new List<Category>
{
new Category { CategoryName = "First", CategoryImagePath = "/Assets/Square.bmp" },
new Category { CategoryName = "Second", CategoryImagePath = null },
};
}
This shows up as follows, which I think is what you're asking:
Well, I want to make the ListViewItem in UWP ,that'll be changing his view on selecting. So I need to change the Visibility property of some elements of ListViewItem on selecting.
I found some way to do this with making custom Style of ListViewItem and Binding IsSelected property like this:
<Style x:Key="VehicleListViewItemStyle" TargetType="ListViewItem" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid Background="Gray" Margin="1">
<Border Margin="2" Padding="10" Background="Gray" >
<StackPanel>
<ContentPresenter x:Name="Presenter1" />
<StackPanel Orientation="Horizontal" Background="Transparent" Margin="-10,0,-9,-9" VerticalAlignment="Center" x:Name="infoPanel"
Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Text="{Binding DeviceID}/> </StackPanel>
</StackPanel>
</Border>
<Border BorderThickness="1" BorderBrush="Orange" Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Its working good, but with this way I cant bind the DeviceID text.
Another one way is creating DataTemplate like this:
<DataTemplate x:Key="monitoringListViewItem" x:Name="item">
<Grid Background="Gray" Margin="1" Width="300" >
<StackPanel>
<ContentPresenter x:Name="Presenter"/>
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/14th_crane_stop.png" Height="50" Width="50" Stretch="Uniform"/>
<StackPanel Orientation="Vertical" Margin="25,0,0,0 "
Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"
>
<TextBlock Text="{Binding DeviceID}" Style="{StaticResource VehicleTextStyle}"/>
<TextBlock Text="{Binding Mark}" Style="{StaticResource VehicleTextStyle}"/>
</StackPanel>
</StackPanel>
</StackPanel >
</Grid>
</DataTemplate>
Now I can bind the text correctly, but cant bind the IsSelected property. I've tried to do this with different Modes, but it still doesn't work because I cant use the TemplatedParent key inside the DataTemplate.
So I need some answers:
-can I bind the text in first way and how can I do that?
-how can I bind the IsSelected property in the second way?
I don't recommend changing the ListViewItem template since you lose all the bells and whistles it provides (selection appearance, ability to be checked, etc).
Using Mode=TemplatedParent in the second snippet won't work because the templated parent from that context is a ListViewItemPresenter, not the ListViewItem (which is the presenter's parent).
It looks like what you're trying to do is to show additional information in the list item when it is selected.
Single selection
C# classes
public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(property, value))
{
return false;
}
property = value;
OnPropertyChanged(propertyName);
return true;
}
}
public class Item : NotifyPropertyChangedBase
{
private string text;
public string Text
{
get { return text; }
set { SetProperty(ref text, value); }
}
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set { SetProperty(ref isSelected, value); }
}
}
public class MainPageViewModel : NotifyPropertyChangedBase
{
public List<Item> Items { get; set; }
private Item selectedItem;
public Item SelectedItem
{
get { return selectedItem; }
set
{
if (selectedItem != value)
{
if (selectedItem != null)
{
selectedItem.IsSelected = false;
}
SetProperty(ref selectedItem, value);
if (selectedItem != null)
{
selectedItem.IsSelected = true;
}
}
}
}
public MainPageViewModel()
{
Items = new List<Item>()
{
new Item() { Text = "Apple" },
new Item() { Text = "Banana" },
};
}
}
MainPage.xaml
<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Item">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Text}"/>
<!-- x:Bind doesn't require visibility converter if min SDK is targeting Anniversary update -->
<TextBlock Text="I'm selected!" Grid.Column="1" Visibility="{x:Bind IsSelected, Mode=OneWay}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new MainPageViewModel();
}
}
Multiple selection
Same as single selection but with the following changes:
MainPageViewModel
public class MainPageViewModel : NotifyPropertyChangedBase
{
public List<Item> Items { get; set; }
public MainPageViewModel()
{
Items = new List<Item>()
{
new Item() { Text = "Apple" },
new Item() { Text = "Banana" },
};
}
public void SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (Item item in e.RemovedItems)
{
item.IsSelected = false;
}
foreach (Item item in e.AddedItems)
{
item.IsSelected = true;
}
}
}
MainPage.xaml
<ListView ItemsSource="{Binding Items}" SelectionChanged="{x:Bind ViewModel.SelectionChanged}" SelectionMode="Extended">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Item">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Text}"/>
<TextBlock Text="I'm selected!" Grid.Column="1" Visibility="{x:Bind IsSelected, Mode=OneWay}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new MainPageViewModel();
}
public MainPageViewModel ViewModel => (MainPageViewModel)DataContext;
}
To answer the actual question in the topic: Yes you can bind ListViewItem.IsSelected quite easily. Make sure your DataTemplate content is wrapped in a ListViewItem.
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:MyItemViewModel">
<ListViewItem IsSelected="{Binding IsSelected, Mode=TwoWay}">
<Grid>
// template content
</Grid>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
Note that there are numerous Q&As here for WPF saying this does not work. It does work with UWP (at least as of SDK 10.0.19041). The WPF answers suggest binding it in the ItemsPanelTemplate or in a ResourceDictionary. For some reason this does not work in UWP.
I did the following and it worked fine
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:PersonalProfile">
<ListViewItem x:Name="root">
<Grid >
<!-- .... -->
<CheckBox IsChecked="{Binding ElementName=root, Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
Dear all i am new to windows phone and xaml.
i have listview on my pivot template now i just want that when i select an item in the listview the backgroud color changed here is my xaml code
<ListView x:Name="LVPrimary" Grid.Row="2" Grid.Column="0"
ItemsSource="{Binding}"
IsItemClickEnabled="True"
ItemClick="LVPrimary_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Width="40" Height="40" CornerRadius="5,5,5,5">
<Border.Background>
<ImageBrush ImageSource="{Binding ImagePath}" />
</Border.Background>
</Border>
<StackPanel Grid.Row="0" Grid.Column="1" Margin="0,0,0,0">
<TextBlock
Text="{Binding Code}"
TextWrapping="Wrap"
Pivot.SlideInAnimationGroup="1"
CommonNavigationTransitionInfo.IsStaggerElement="True"
Style="{ThemeResource ListViewItemTextBlockStyle}"
Margin="0,0,19,0"/>
<TextBlock
TextWrapping="NoWrap" TextTrimming="CharacterEllipsis"
Text="{Binding Name}"
Pivot.SlideInAnimationGroup="2"
CommonNavigationTransitionInfo.IsStaggerElement="True"
Style="{ThemeResource ListViewItemContentTextBlockStyle}"
Margin="0,0,5,0"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Sorry for the late reply. You will have a List<ItemClass> and ObservableCollection<ItemClass>.
What you can do is - Define a SolidColorBrush Property and bind this property to your Item Grid. I have created this example : -
Here is my Item Class : - Make sure you Implement INotifyPropertyChanged.
public class Item : INotifyPropertyChanged
{
public string Something { get; set; }
public SolidColorBrush ItemBackground
{
get { return _itemBackground; }
set
{
_itemBackground = value;
OnPropertyChanged("ItemBackground");
}
}
private SolidColorBrush _itemBackground;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
And My sample & simple Xaml is :-
<ListView x:Name="LVPrimary" IsItemClickEnabled="True" ItemClick="ListViewBase_OnItemClick">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="{Binding ItemBackground}" Height="100" Width="200">
<TextBlock Text="{Binding Something}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And on Onlick Event I just changed the color of the clicked item like this :-
private void ListViewBase_OnItemClick(object sender, ItemClickEventArgs e)
{
((Item)e.ClickedItem).ItemBackground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
}
Hope it will help you.
Below solution works fine for me..
var griditem = ListViewName.ContainerFromItem(ListViewName.SelectedItem);
var a = ((Windows.UI.Xaml.Controls.Panel)((Windows.UI.Xaml.Controls.ContentControl)listViewItem).ContentTemplateRoot
a.Background= new SolidColorBrush(Windows.UI.Colors.Red);
var textitem = ListViewName.ContainerFromItem(ListViewName.SelectedItem);
var a = ((Windows.UI.Xaml.Controls.Panel)((Windows.UI.Xaml.Controls.ContentControl)listViewItem).ContentTemplateRoot).Children;
((TextBlock)a.ElementAt(0)).Text= "Your Text";
I am using the Telerik's RadCalendar control for my WindowsPhone application. I want to change the SelectedDate's Background color in RadCalendar of WindowsPhone... Is there any way to change this ?
You can change the SelectedDay's properties through using a Special Template. Here is a sample data template for a day:
<telerikInput:RadCalendar>
<telerikInput:RadCalendar.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<TextBlock Text="{Binding DetailText}" FontSize="7" MaxHeight="25" VerticalAlignment="Top" Margin="0,-2,0,0" />
<TextBlock Text="{Binding Text}" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
</Grid>
</DataTemplate>
</telerikInput:RadCalendar.ItemTemplate>
</telerikInput:RadCalendar>
Example of a special template for weekends
<?xml version="1.0" encoding="utf-8"?>
<UserControl.Resources>
<local:WeekendDaySelector x:Key="WeekendDaySelector">
<local:WeekendDaySelector.SpecialTemplate>
<DataTemplate>
<Grid Margin="5">
<Image Source="/Calendar/Images/SpecialDay.png" Width="24" Height="24" />
<TextBlock Text="{Binding Text}" x:Name="TextPresenter" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
</Grid>
</DataTemplate>
</local:WeekendDaySelector.SpecialTemplate>
</local:WeekendDaySelector>
</UserControl.Resources>
<telerikInput:RadCalendar ItemTemplateSelector="{StaticResource WeekendDaySelector}" />
Now the template selector
public class WeekendDaySelector : DataTemplateSelector
{
public DataTemplate SpecialTemplate
{
get;
set;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
CalendarButtonContentInfo info = item as CalendarButtonContentInfo;
CalendarButton button = container as CalendarButton;
if (!button.IsFromCurrentView) return null;
if (info.Date == null) return null;
if (info.Date.Value.DayOfWeek == DayOfWeek.Saturday ||
info.Date.Value.DayOfWeek == DayOfWeek.Sunday)
{
return SpecialTemplate;
}
return base.SelectTemplate(item, container);
}
}
You can learn more in this thread.