GetContainerForItemOverride method working in WinUI UWP
but not working in Uno Platform.
how to do GetContainerForItemOverride???
this is Implemented Method in Uno platform reference Docs > Itemcontrol(https://platform.uno/docs/articles/implemented/windows-ui-xaml-controls-itemscontrol.html)
anyway. this is my code
public partial class Breadcrumb : ListView
{
public Breadcrumb()
{
this.DefaultStyleKey = typeof(Breadcrumb);
}
protected override DependencyObject GetContainerForItemOverride()
{
return new BreadcrumbItem();
}
}
public partial class BreadcrumbItem : ListViewItem
{
public BreadcrumbItem()
{
var test = this.Content;
this.DefaultStyleKey = typeof(BreadcrumbItem);
this.Loaded += OnLoaded;
}
........
}
XAML
<Style TargetType="controls:Breadcrumb">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Breadcrumb">
.......Text....
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="controls:BreadcrumbItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border
Margin="4"
Padding="4"
Background="Red">
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" />
<TextBlock
x:Name="separator"
HorizontalAlignment="Right"
Text=" / " />
</Grid>
</Border>
<!-- mouse over -->
<!-- IsSelected -->
<!-- IsFirst -->
<!-- IsLast -->
<!-- <ControlTemplate.VisualTree -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ItemsSources
xmlns:c="using:My.Controls"
<StackPanel Orientation="Horizontal">
<c:Breadcrumb ItemsSource="{x:Bind HistoryItemsSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
NavigationHistoryControl.cs
[ContentProperty(Name = "HistoryItemsSource")]
public sealed partial class NavigationHistoryControl : UserControl, INotifyPropertyChanged
{
public NavigationHistoryControl()
{
this.InitializeComponent();
this.HistoryItemsSource = new List<NavigationItem>()
{
new NavigationItem(){
Content = "Content1",
Icon = new SymbolIcon(Symbol.Home),
ViewPathType= typeof(Views.View1)
},
new NavigationItem(){
Content = "Content2",
Icon = new SymbolIcon(Symbol.Home),
ViewPathType= typeof(Views.View2)
},
};
public IEnumerable<NavigationItem> HistoryItemsSource
{
get { return (IEnumerable<NavigationItem>)GetValue(HistoryItemsSourceProperty); }
set => SetValue(HistoryItemsSourceProperty, value);
}
public static readonly DependencyProperty HistoryItemsSourceProperty = DependencyProperty.Register("HistoryItemsSource", typeof(IEnumerable<NavigationItem>), typeof(NavigationHistoryControl), new PropertyMetadata(null));
public event PropertyChangedEventHandler PropertyChanged;
}
Related
Problem
Visual state manager does not kick in
How do I change background of
the selected frame?
Any suggestions of what I am doing wrong?
I need to create an horizontal list with a set of frames that when selected change background color.
The obvious implementation would be a collectionView and that has a SelectedItem that would just work , so what is the problem with that?
Well if you have a pancakeView/frame with rounded corners in iOS you can see the grey background and its a bug reported in xamarin forms.
So I decided to implement a bindableLayout, this works fine however I have tried all sorts but I cannot change the background color of the pancake/frame and a label on selection , below is what I have done
MAIN PAGE
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightSkyBlue" />
<Setter TargetName="LabelA" Property="Label.TextColor" Value="Red"/>
<Setter TargetName="Labelb" Property="Label.TextColor" Value="Red"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<FlexLayout x:Name="Flex"
Direction="Row"
BindableLayout.ItemsSource="{Binding Cities}"
Position="Relative"
AlignItems="Start"
FlowDirection="LeftToRight"
JustifyContent="SpaceEvenly">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid x:Name="myGrid" Padding="8,0" FlexLayout.AlignSelf="Start" >
<pancakeView:PancakeView x:Name="myPancake"
Padding="20"
Margin="5"
CornerRadius="5"
WidthRequest="60"
HeightRequest="60"
BackgroundColor="White" >
<pancakeView:PancakeView.Border>
<pancakeView:Border Thickness="1" Color="Blue" />
</pancakeView:PancakeView.Border>
<StackLayout >
<Label x:Name="LabelA" Margin="0,0,0,0"
Text="{Binding Name }"
TextColor="Gray"
HorizontalOptions="Center" VerticalOptions="Center">
</Label>
<Label x:Name="Labelb" VerticalOptions="EndAndExpand"
HorizontalTextAlignment="Center"
TextColor="Gray"
FontSize="12"
Text="SomeText Here" />
</StackLayout>
<pancakeView:PancakeView.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_OnTapped">
</TapGestureRecognizer>
</pancakeView:PancakeView.GestureRecognizers>
</pancakeView:PancakeView>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
</ContentPage>
MAIN PAGE CODE BEHIND
using System;
using Xamarin.Forms;
namespace BlankApp2.Views
{
public partial class MainPage
{
string currentColorState = "Normal";
public MainPage()
{
InitializeComponent();
}
private void TapGestureRecognizer_OnTapped(object sender, EventArgs e)
{
currentColorState = currentColorState == "Normal" ? "Focused" : "Normal";
//below has errors since "myPancake, LabelA Labelb are not recognized WHY????
// VisualStateManager.GoToState(myPancake,_currentColorState);
// VisualStateManager.GoToState(LabelA, _currentColorState);
// VisualStateManager.GoToState(Labelb, _currentColorState);
}
}
}
VIEWMODEL
using Prism.Navigation;
using System.Collections.ObjectModel;
namespace BlankApp2.ViewModels
{
public class MainPageViewModel : ViewModelBase
{
public MainPageViewModel(INavigationService navigationService)
: base(navigationService)
{
Title = "Main Page";
Cities = GetCities();
}
private ObservableCollection<City> cities;
public ObservableCollection<City> Cities
{
get => cities;
set => SetProperty(ref cities, value);
}
private ObservableCollection<City> GetCities()
{
var list = new ObservableCollection<City>
{
new City {Name = "London"},
new City {Name = "Rome"},
new City {Name = "New York"}
};
return list;
}
}
public class City
{
public string Name { get; set; }
}
}
Try to add VisualStateManager.VisualStateGroups your frame/pancakeviw(Here I'm testing with frame).
create a custom frame:
class MyFrame :Frame
{
public bool IsFoucs { get; set; }
}
the page.xaml:
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="local:MyFrame">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" >
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
<Setter TargetName="LabelA" Property="Label.TextColor" Value="Gray"/>
<Setter TargetName="Labelb" Property="Label.TextColor" Value="Gray"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightSkyBlue" />
<Setter TargetName="LabelA" Property="Label.TextColor" Value="Red"/>
<Setter TargetName="Labelb" Property="Label.TextColor" Value="Red"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<FlexLayout x:Name="Flex"
Direction="Row"
BindableLayout.ItemsSource="{Binding Cities}"
Position="Relative"
AlignItems="Start"
FlowDirection="LeftToRight"
JustifyContent="SpaceEvenly">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid x:Name="myGrid" Padding="8,0" FlexLayout.AlignSelf="Start" >
<local:MyFrame x:Name="myPancake"
Padding="20"
Margin="5"
CornerRadius="5"
WidthRequest="60"
HeightRequest="60"
BorderColor="Blue"
BackgroundColor="White" >
<StackLayout >
<Label x:Name="LabelA" Margin="0,0,0,0"
Text="{Binding .}"
TextColor="Gray"
HorizontalOptions="Center" VerticalOptions="Center">
</Label>
<Label x:Name="Labelb" VerticalOptions="EndAndExpand"
HorizontalTextAlignment="Center"
TextColor="Gray"
FontSize="12"
Text="SomeText Here" />
</StackLayout>
<local:MyFrame.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_OnTapped">
</TapGestureRecognizer>
</local:MyFrame.GestureRecognizers>
</local:MyFrame>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
then in the page.cs:
private void TapGestureRecognizer_OnTapped(object sender, EventArgs e)
{
foreach (var item in Flex.Children)
{
MyFrame frame = (MyFrame)item.FindByName("myPancake");
frame.IsFoucs = false;
VisualStateManager.GoToState(frame, "Normal");
}
MyFrame myFrame = sender as MyFrame;
myFrame.IsFoucs = !myFrame.IsFoucs;
VisualStateManager.GoToState(myFrame, myFrame.IsFoucs ? "Focused" : "Normal");
}
the effect is like below:
i have a collection
<CollectionView SelectionMode="Single"
ItemsSource="{Binding Cities}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="5">
<Image Source="{Binding Image}" />
<Label TextColor="Black" text="Text"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
How can i painting with diferents colors the image and label when i select a item?
According to your description, you have Image and Label in CollectionView DataTemplate, you want to set Image and Label different background color when you select one item, am I right?
If yes, I suggest you can use binding Background color to do this, please take a look my code:
<ContentPage.Resources>
<Style TargetType="StackLayout">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<CollectionView
ItemsSource="{Binding images}"
SelectionChanged="CollectionView_SelectionChanged"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="5">
<Frame BackgroundColor="{Binding imagecolor}" CornerRadius="5">
<Image Source="{Binding Image}" />
</Frame>
<Label
BackgroundColor="{Binding labelcolor}"
Text="{Binding cityname}"
TextColor="Black" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage.Content>
public partial class Page3 : ContentPage
{
public ObservableCollection<imagemodel> images { get; set; }
public Page3()
{
InitializeComponent();
images = new ObservableCollection<imagemodel>()
{
new imagemodel(){Image="a5.jpg",cityname="beijing",imagecolor=Color.White,labelcolor=Color.White},
new imagemodel(){Image="a6.jpg",cityname="shanghai",imagecolor=Color.White,labelcolor=Color.White},
new imagemodel(){Image="a7.jpg",cityname="shenzhen",imagecolor=Color.White,labelcolor=Color.White},
new imagemodel(){Image="a8.jpg",cityname="xiamen",imagecolor=Color.White,labelcolor=Color.White}
};
this.BindingContext = this;
}
private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
imagemodel previous = (e.PreviousSelection.FirstOrDefault() as imagemodel);
imagemodel current = (e.CurrentSelection.FirstOrDefault() as imagemodel);
//Set the current to the color you want
current.imagecolor = Color.Pink;
current.labelcolor = Color.Green;
if (previous != null)
{
//Reset the previous to defaulr color
previous.imagecolor = Color.White;
previous.labelcolor = Color.White;
}
}
}
public class imagemodel:ViewModelBase
{
public string Image { get; set; }
public string cityname { get; set; }
private Color _imagecolor;
public Color imagecolor
{
get { return _imagecolor; }
set
{
_imagecolor = value;
RaisePropertyChanged("imagecolor");
}
}
private Color _labelcolor;
public Color labelcolor
{
get { return _labelcolor; }
set
{
_labelcolor = value;
RaisePropertyChanged("labelcolor");
}
}
}
The ViewModelbase implement INotifyPropertyChanged interface:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Update:
If you want to use mvvm mode to do this, and put CollectionView_SelectionChanged method in my viewModel, I suggest you can bind SelectionChangedCommand to do this, please take a look my code:
The ContentPage:
<ContentPage.Resources>
<Style TargetType="StackLayout">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<CollectionView
ItemsSource="{Binding images}"
SelectedItem="{Binding CurrentSelection}"
SelectionChangedCommand="{Binding selectioncommand}"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="5">
<Frame BackgroundColor="{Binding imagecolor}" CornerRadius="5">
<Image Source="{Binding Image}" />
</Frame>
<Label
BackgroundColor="{Binding labelcolor}"
Text="{Binding cityname}"
TextColor="Black" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage.Content>
public partial class Page3 : ContentPage
{
public Page3()
{
InitializeComponent();
this.BindingContext = new imageviewmodel();
}
}
The imageviewmodel.cs:
public class imageviewmodel:ViewModelBase
{
public ObservableCollection<imagemodel> images { get; set; }
private imagemodel _PreviousSelection;
public imagemodel PreviousSelection
{
get { return _PreviousSelection; }
set
{
_PreviousSelection = value;
RaisePropertyChanged("PreviousSelection");
}
}
private imagemodel _CurrentSelection;
public imagemodel CurrentSelection
{
get { return _CurrentSelection; }
set
{
if(CurrentSelection!=value)
{
PreviousSelection = CurrentSelection;
_CurrentSelection = value;
RaisePropertyChanged("CurrentSelection");
}
}
}
public Command selectioncommand { get; set; }
public imageviewmodel()
{
images = new ObservableCollection<imagemodel>()
{
new imagemodel(){Image="a5.jpg",cityname="beijing",imagecolor=Color.White,labelcolor=Color.White},
new imagemodel(){Image="a6.jpg",cityname="shanghai",imagecolor=Color.White,labelcolor=Color.White},
new imagemodel(){Image="a7.jpg",cityname="shenzhen",imagecolor=Color.White,labelcolor=Color.White},
new imagemodel(){Image="a8.jpg",cityname="xiamen",imagecolor=Color.White,labelcolor=Color.White}
};
selectioncommand = new Command(changecolor);
}
private void changecolor()
{
foreach(imagemodel model in images)
{
if(model.cityname==CurrentSelection.cityname)
{
model.imagecolor = Color.Pink;
model.labelcolor = Color.Green;
}
else if(PreviousSelection != null && model.cityname==PreviousSelection.cityname)
{
model.imagecolor = Color.White;
model.labelcolor = Color.White;
}
}
}
}
The screenshot is same.
The screenshot:
I am trying to bind my ViewModelBase in a ResourceDictionary so that I can call some of the properties to set the properties on my controls, for example I have a label and I want to set its color by one of the properties in my ViewModelBase...
Update: The ResourceDictionary resides in my styles folder and gets called on bootup, it does not reside in a page like so...
void LoadStyles()
{
if (IsASmallDevice())
{
MyResources.MergedDictionaries.Add(SmallDevicesStyle.SharedInstance);
}
else
{
MyResources.MergedDictionaries.Add(GeneralDevicesStyle.SharedInstance);
}
}
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:MyApp.ViewModels"
mc:Ignorable="d"
x:Class="MyApp.Styles.GeneralDevicesStyle">
<viewModels:ViewModelBase x:Key="BaseView"/>
<OnIdiom x:TypeArguments="x:Double" Tablet="30" Phone="10" x:Key="PageSpacing" />
<OnIdiom x:TypeArguments="Thickness" Tablet="10" Phone="10" x:Key="PagePadding" />
<Style TargetType="Label" x:Key="LabelStyle1">
<Setter Property="FontSize">
<Setter.Value>
<OnIdiom x:TypeArguments="x:Double" Phone="15" Tablet="15"/>
</Setter.Value>
</Setter>
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
<Setter Property="VerticalOptions" Value="FillAndExpand" />
<Setter Property="BackgroundColor" Value="{Binding DefaultLabelColor}" />
</Style>
</ResourceDictionary>
public class ViewModelBase : BaseViewModel
{
sting BackGroundColor = "aqua";
public string DefaultBackGroundColor { get return BackGroundColor; }
}
So my question is, How can I bind my ViewModelBase in my ResourceDictionary so that I can access the properties/Methods that reside in the ViewModelBase?
You need to set the BindingContext for Label.
ViewModelBase:
public class ViewModelBase
{
//public string DefaultBackGroundColor { get; set; } = "Aqua";
private string BackGroundColor = "Aqua";
public string DefaultBackGroundColor
{
get { return BackGroundColor; }
}
}
Xaml:
<ContentPage.Resources>
<ResourceDictionary>
<viewModels:ViewModelBase x:Key="BaseView" />
</ResourceDictionary>
<Style TargetType="Label">
<Setter Property="BackgroundColor" Value="{Binding DefaultBackGroundColor}" />
<Setter Property="BindingContext" Value="{StaticResource BaseView}"></Setter>
</Style>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<Label
HorizontalOptions="CenterAndExpand"
Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
I've Xamarin Forms app and I have Listview which looks like this :
<ListView x:Name="CalendarList" VerticalOptions="FillAndExpand" VerticalScrollBarVisibility="Never" RowHeight="100"
Grid.Row="0" SeparatorVisibility="None" ItemTapped="CalendarList_OnItemSelected" BackgroundColor="Transparent" >
<ListView.ItemTemplate>
<DataTemplate>
<local:MyCell>
<pcv:PancakeView **x:Name="YearsContainer"** Margin = "0,10,0,10" Style="{StaticResource cell_years}" IsClippedToBounds="true" >
<StackLayout HorizontalOptions = "StartAndExpand" Orientation="Horizontal">
<Label Style = "{DynamicResource bold_label}" Text="{Binding Year}" VerticalOptions="Center" />
</StackLayout>
</pcv:PancakeView>
</local:MyCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
private async void CalendarList_OnItemSelected(object sender, EventArgs e)
{
await Task.Delay(350);
var selectedItem = ((ListView)sender).SelectedItem;
var item = ((YearsList)selectedItem);
((ListView)sender).SelectedItem = null;
vm.ViewDetailCommand.Execute(item); // goto details page
}
public class MyCell: ViewCell
{
protected async override void OnTapped()
{
base.OnTapped();
await Task.Run(async () => await AnimationHelper.AnimateClick(this.View));
}
}
//IOS Renderer
[assembly: ExportRenderer(typeof(MyCell), typeof(MyCellRenderer))]
namespace CountDown.iOS.Renderers
{
public class MyCellRenderer : ViewCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
if (cell != null)
{
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
}
return cell;
}
}
}
Now the question is :
Is it possible to change the style for PCV: PancakeView to different style names once a cell is selected?
I'm using Xamarin Forms ver 4.3.0 btw.
I've been able to change the color of the whole cell but I am not sure how to change the style.
According to your description, I guess that you want to change PancakeView style in ListView ItemTapped event?
If yes, I do one sample that you can take a look. I use Label control instead of PancakeView, it is the same.
<ContentPage.Resources>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="TextColor" Value="Color.Black" />
<Setter Property="FontAttributes" Value="None" />
</Style>
<Style x:Key="LabelChangedStyle" TargetType="Label">
<Setter Property="TextColor" Value="Color.Red" />
<Setter Property="FontAttributes" Value="Bold" />
</Style>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<ListView ItemTapped="ListView_ItemTapped" ItemsSource="{Binding model3s}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Style="{Binding LabelStyle}" Text="{Binding str}">
<Label.Triggers>
<DataTrigger
Binding="{Binding istap}"
TargetType="Label"
Value="true">
<Setter Property="Style" Value="{StaticResource LabelChangedStyle}" />
</DataTrigger>
</Label.Triggers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
public partial class Page12 : ContentPage
{
public ObservableCollection<model3> model3s { get; set; }
public model3 model;
public Page12 ()
{
InitializeComponent ();
model3s = new ObservableCollection<model3>()
{
new model3(){str="this is test!",istap=false },
new model3(){str="this is test!",istap=false},
new model3(){str="this is test!",istap=false},
new model3(){str="this is test!",istap=false},
new model3(){str="this is test!",istap=false}
};
this.BindingContext = this;
}
private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
if(model!=null)
{
model.istap = false;
}
model3 m = e.Item as model3;
m.istap = true;
model = m;
}
}
public class model3:ViewModelBase
{
public string str { get; set; }
private bool _istap;
public bool istap
{
get { return _istap; }
set
{
_istap = value;
RaisePropertyChanged("istap");
}
}
}
The ViewModelBase is the class that implement INotifyPropertyChanged
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
When you tap one item in ListView, the style will change.
When I change selection in combo box debugger will hit TestSelectedItem {set} in User class, but I want to hit debugger, TestSelectedItem {set} in MainWindow class. Please suggests me correct solution.
public class User
{
public string Name { get; set; }
public ObservableCollection<string> TypeCollection { get; set; }
private string _testSelectedItem;
public string TestSelectedItem
{
get { return _testSelectedItem; }
set { _testSelectedItem = value; }
}
public User()
{
TypeCollection = new ObservableCollection<string>();
TypeCollection.Add("A");
TypeCollection.Add("B");
TypeCollection.Add("C");
}
}
public partial class MainWindow : Window
{
public List<User> Users { get; set; }
private string _testSelectedItem;
public string TestSelectedItem
{
get { return _testSelectedItem; }
set { _testSelectedItem = value; }
}
public MainWindow()
{
InitializeComponent();
Users = new List<User>();
Users.Add(new User() { Name = "User 1" });
Users.Add(new User() { Name = "User 2" });
Users.Add(new User() { Name = "User 3" });
myGrid.DataContext = this;
}
}
<Window x:Class="WpfApplication11.MainWindow"
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:local="clr-namespace:WpfApplication11"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Name ="myGrid">
<StackPanel>
<DataGrid Name="MyDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Users}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"
Header="Name"
Width="90"
CanUserResize="False"
CanUserSort="False"
CanUserReorder="False"
IsReadOnly="True" />
<DataGridComboBoxColumn Header="Product Type"
DisplayMemberPath="ProductType"
SelectedValuePath="ProductTypeId"
SelectedValueBinding="{Binding SelectedValuePath, UpdateSourceTrigger=PropertyChanged}">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding TypeCollection}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding TypeCollection}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<DataGridTemplateColumn Header="Bug">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<ComboBox Height="25" Width="200"
x:Name ="ppCombo"
ItemsSource="{Binding TypeCollection }"
SelectedItem="{Binding TestSelectedItem ,Mode=TwoWay ,UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
</Window>
I think I just found a solution but not sure is that the correct one
SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, Path=TestSelectedItem}">