I have an ObservableCollection that generates a button with the data of a Model in which I pass an image, a color and a link. The problem is that I want to put a method in it and when I press the button, call the method that I put into the ObservableCollection.
[Edited]
I am making a FloatingButton like this:
This floating button is made with a custom control. Each small button has a background color, an image and a link which are in Items.cs. In the viewmodel, I create an ObservableCollections with the Items.cs data that every time I add a list, a new button is added. What I want to do is to be able to add in addition to an image, a link and a color, a method that depending on the button you press, does what I want.
If I press the first small button that will be the first index in the list, that when I press it, it does one thing, and if I press the fourth button it will call another method that I want.
Example:
ItemList.Add(new Items { Website = "https://google.es/", Image = "web.png", ColorButton = "#B52D50", Method = "DoSomething" });
ItemList.Add(new Items { Website = "https://facebook.com/", Image = "facebook.png", ColorButton = "#B52D50", Method = "OpenFacebookApp" });
public void DoSomething()
{
//Do Something
}
public void OpenFacebookApp()
{
//Open Facebook App
}
This is my code:
ViewModel.cs:
public class ViewModel : INotifyPropertyChanged
{
//==============================================================
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//==============================================================
string imageprimarybutton;
public string FirstImage
{
get => imageprimarybutton; set
{
imageprimarybutton = value;
OnPropertyChanged();
}
}
//=============
string firstButtonColor;
public string FirstButtonColor
{
get => firstButtonColor; set
{
firstButtonColor = value;
OnPropertyChanged();
}
}
//=============
private bool isVisible;
public bool IsVisible
{
get => isVisible;
set
{
isVisible = value;
OnPropertyChanged();
}
}
//=============
public ICommand LaunchWeb { get; private set; }
public ICommand OpenFloating { get; private set; }
public ObservableCollection<Items> ItemList { get; set; }
//=============
public ViewModel()
{
IsVisible = false;
FirstImage = "dots.png";
FirstButtonColor = "#B52D50";
OpenFloating = new Command(openFloatingButton);
LaunchWeb = new Command(async (url) =>
{
string AppLink = (string)url;
await Launcher.TryOpenAsync(AppLink);
});
ItemList = new ObservableCollection<Items>();
ItemList.Add(new Items { Website = "https://facebook.com/", Image = "facebook.png", ColorButton = "#B52D50" /*What I want: Method=OpenApp*/});
ItemList.Add(new Items { Website = "https://twitter.com/", Image = "twitter.png", ColorButton = "#B52D50" });
ItemList.Add(new Items { Website = "https://www.instagram.com/", Image = "insta.png", ColorButton = "#B52D50" });
ItemList.Add(new Items { Website = "https://google.com/", Image = "web.png", ColorButton = "#B52D50" });
}
/* And here the method I call in ItemList
public void OpenApp() {
Do something
}
*/
bool firstStart = true;
bool nextClick = true;
public void openFloatingButton()
{
if (firstStart)
{
FirstImage = "cross.png";
FirstButtonColor = "#6F1B31";
IsVisible = true;
firstStart = false;
}
else
{
if (nextClick)
{
FirstImage = "dots.png";
FirstButtonColor = "#B52D50";
IsVisible = false;
nextClick = false;
}
else
{
FirstImage = "cross.png";
FirstButtonColor = "#6F1B31";
IsVisible = true;
nextClick = true;
}
}
}
}
Items.cs:
public class Items : INotifyPropertyChanged
{
string url, image, color;
public string Website
{
get { return url; }
set {
url = value;
OnPropertyChanged("url");
}
}
public string Image
{
get {
return image;
}
set{
image = value;
OnPropertyChanged("image");
}
}
public string ColorButton{
get {
return color;
}
set{
color = value;
OnPropertyChanged("color");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I wrote a simple example for you and hope you can understand how the binding works.
First I add a Name property in the Items model which is use for distinguish different button:
public class Items : INotifyPropertyChanged
{
string url { get; set; }
string image { get; set; }
string color { get; set; }
string name { get; set; }
public string Website
{
get { return url; }
set
{
url = value;
OnPropertyChanged("Website");
}
}
public string Image
{
get
{
return image;
}
set
{
image = value;
OnPropertyChanged("Image");
}
}
public string ColorButton
{
get
{
return color;
}
set
{
color = value;
OnPropertyChanged("ColorButton");
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then in the View Model, there is a MethodCommand which you can bind to the buttons:
public class viewModel {
public ObservableCollection<Items> ItemList { get; set; }
public ICommand MethodCommand { get; set; }
public viewModel()
{
ItemList = new ObservableCollection<Items>();
ItemList.Add(new Items { Website = "https://facebook.com/", Image = "facebook.png", ColorButton = "#B52D50", Name = "facebook"/*What I want: Method=OpenApp*/});
ItemList.Add(new Items { Website = "https://twitter.com/", Image = "twitter.png", ColorButton = "#B52D50", Name = "twitter" });
ItemList.Add(new Items { Website = "https://www.instagram.com/", Image = "insta.png", ColorButton = "#B52D50", Name = "insta" });
ItemList.Add(new Items { Website = "https://google.com/", Image = "web.png", ColorButton = "#B52D50", Name = "web" });
MethodCommand = new Command(test);
}
private void test(object obj)
{
string itemName= obj as string;
Console.WriteLine(itemName);
if (itemName == "facebook")
{
//perform your method with facebook
}
else if (itemName == "twitter")
{
//perform your method with twitter
}
else if (itemName == "insta")
{
//...
}
else
{
//...
}
}
}
Here is the code in Xaml, bind the MethodCommand to the Command and bind Name to the CommandParameter:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage 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"
mc:Ignorable="d"
x:Name="myPage"
x:Class="App416.MainPage">
<CollectionView ItemsSource="{Binding ItemList}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="1"
Text="{Binding Name}"
Command="{Binding Source={x:Reference myPage}, Path=BindingContext.MethodCommand}"
CommandParameter="{Binding Name}"
/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
And at last, set the bindingContext in MainPage:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new viewModel();
}
}
Please feel free to ask me any question if you have:).
Related
I have implemented horizontal list using collection view in Xamarin forms. The Underline doesn't come properly it will be late while selecting Item. The Refreshing is too late. AS you can see in the following Video
My Xaml Code
<CollectionView
x:Name="rooms_List"
IsEnabled="True"
SelectedItem="{Binding SelectedRoom}"
SelectionChangedCommand="{Binding Source={x:Reference ThePage}, Path= BindingContext.RoomChanged}"
ItemsLayout = "HorizontalList"
SelectionChanged="RoomCollectionSelectionChanged"
BackgroundColor = "white"
HeightRequest="50"
SelectionMode="Single"
HorizontalScrollBarVisibility="Never"
ItemsSource="{Binding RoomList}">
<CollectionView.ItemTemplate >
<DataTemplate>
<Grid>
<StackLayout VerticalOptions="Start" Orientation="Vertical">
<Label Text ="{Binding RoomName}" Padding="20,10,20,0" />
<BoxView x:Name="line" HeightRequest="3" IsVisible="{Binding IsSelected}" BackgroundColor="#1484B8" WidthRequest="5" Margin="18,0,15,0" />
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
My Xaml.cs RoomCollectionSelectionChanged
private void RoomCollectionSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.Count == 0)
{
room_image.IsVisible = true;
}
else
{
var selectedItem = e.CurrentSelection.FirstOrDefault() as Room;
selectedRoom = selectedItem.RoomName;
if (selectedRoom == "All")
{
room_image.IsVisible = false;
}
else if (e.PreviousSelection.Count == 1)
{
var previousItem = (e.PreviousSelection.FirstOrDefault() as Room)?.RoomName;
if (previousItem != "")
{
room_image.IsVisible = true;
room_image.Source = selectedItem.RoomImage;
}
}
else
{
room_image.IsVisible = true;
room_image.Source = selectedItem.RoomImage;
}
}
}
My ViewModel
private ObservableCollection<Room> roomList { get; set; }
public ObservableCollection<Room> RoomList
{
get { return roomList; }
set
{
roomList = value;
OnPropertyChanged(nameof(RoomList));
}
}
private Room selectedRoom { get; set; }
public Room SelectedRoom
{
get { return selectedRoom; }
set
{
selectedRoom = value;
}
}
public bool isSelected { get; set; }
public bool IsSelected
{
get { return isSelected; }
set
{
if (value != isSelected)
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
}
private Room previousSelectedRoom;
private void SelectedRoomEvent()
{
if (SelectedRoom != null)
{
DevicePage.checkRoom = true;
string RoomName = SelectedRoom.RoomName;
if (RoomName.Equals("All"))
{
GetDeviceAndRoomData();
}
else
{
int RoomId = SelectedRoom.RoomId;
if (previousSelectedRoom != null)
{
previousSelectedRoom.IsSelected = false;
}
previousSelectedRoom = SelectedRoom;
previousSelectedRoom.IsSelected = true;
}
}
My Model
public class Room
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[JsonProperty("roomId")]
public int RoomId { get; set; }
[JsonProperty("serialNumber")]
public string SerialNumber { get; set; }
[JsonProperty("roomName")]
public string RoomName { get; set; }
[JsonProperty("roomImage")]
public string RoomImage { get; set; }
[JsonIgnore]
public bool IsSelected { get; set; }
}
Please give suggestions how to fix this enter image description here
I see you use e. PreviousSelection in your code. That is better than what I was doing in my repository, so I have modified github ToolmakerSteve - repo XFIOSHorizCollViewScrollBug to use that.
I made changes in several places in this file:
using System.Collections.ObjectModel;
using System.Linq;
using Xamarin.Forms;
namespace XFIOSHorizCollViewScrollBug
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
InitRoomList();
BindingContext = this;
// After set BindingContext, so RoomCollectionSelectionChanged gets called.
var room = RoomList[0];
rooms_List.SelectedItem = room;
}
public ObservableCollection<Room> RoomList { get; set; }
private void RoomCollectionSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var previousItem = e.PreviousSelection.FirstOrDefault() as Room;
DeselectRoom(previousItem);
var selectedItem = e.CurrentSelection.FirstOrDefault() as Room;
SelectRoom(selectedItem);
}
private void DeselectRoom(Room room)
{
if (room != null)
{
room.IsSelected = false;
}
}
private void SelectRoom(Room room)
{
if (room != null) {
room.IsSelected = true;
rooms_List.ScrollTo(room, position: ScrollToPosition.Center, animate: false);
}
}
string[] roomNames = new string[] {
"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"
};
private void InitRoomList()
{
var rooms = new ObservableCollection<Room>();
foreach (var name in roomNames) {
rooms.Add(new Room(name));
}
RoomList = rooms;
}
}
}
The other files are the same as in my answer to your previous question.
Please download my repository, build and run it, verify that it works. The change to underline happens INSTANTLY - as soon as you click on an item.
Then compare that to your code. Change your code until it matches what the working repo does.
im working on an Mobile App for Android in Xamarin Forms, and have one problem. I have a ObservableCollection that i fill with the following Model.
private int _category_ID;
public int Category_ID
{
get
{
return _category_ID;
}
set
{
_category_ID = value;
OnPropertyChanged("_category_ID");
}
}
private string _category_Name;
public string Category_Name
{
get
{
return _category_Name;
}
set
{
_category_Name = value;
OnPropertyChanged("_category_Name");
}
}
private string _category_Description;
public string Category_Description
{
get
{
return _category_Description;
}
set
{
_category_Description = value;
OnPropertyChanged("_category_Description");
}
}
public CategoryModel(string name, List<ProductModel> products) : base(products)
{
Category_Name = name;
}
That works fine and all Categorys and Items shows right when i Debugging in the ObservableCollection. Example: Categroy 1 = 2 Items Category 2 = 3 Items Category 3 = 4 Items.
That works.
But my problem is, that when i use a CollectionView like this
<CollectionView ItemsSource="{Binding ObservCollectionCategory}" IsGrouped="True">
<CollectionView.ItemTemplate>
<DataTemplate>
<ScrollView>
<Grid Padding="10">
<StackLayout BackgroundColor="Blue">
<Label Text="{Binding Product_Name}"/>
<Label Text="{Binding Product_Description}"/>
</StackLayout>
</Grid>
</ScrollView>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.GroupHeaderTemplate>
<DataTemplate >
<Label Text="{Binding Category_Name}"/>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
</CollectionView>
The View shows me only the first item of the last categroy and the other ignores. All other Categorys shows right.
When i create a blank Categroy at the end of the ObservableCollection then all Items, from the last category, shows in the View. But i have an empty Group then at the end.
I have try to show me the count in the header, and the count the right one (4).
You could try the code below.
Model:
public class ProductModel : INotifyPropertyChanged
{
private string _product_Name;
public string Product_Name
{
get
{
return _product_Name;
}
set
{
_product_Name = value;
OnPropertyChanged("Product_Name");
}
}
private string _product_Description;
public string Product_Description
{
get
{
return _product_Description;
}
set
{
_product_Description = value;
OnPropertyChanged("Product_Description");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class CategoryModel : List<ProductModel>, INotifyPropertyChanged
{
private string _category_Name;
public event PropertyChangedEventHandler PropertyChanged;
public string Category_Name
{
get
{
return _category_Name;
}
set
{
_category_Name = value;
OnPropertyChanged("Category_Name");
}
}
public CategoryModel(string name, List<ProductModel> diary) : base(diary)
{
Category_Name = name;
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Code behind:
public ObservableCollection<CategoryModel> ObservCollectionCategory { get; set; } = new ObservableCollection<CategoryModel>();
public Page18()
{
InitializeComponent();
ObservCollectionCategory.Add(new CategoryModel("Categroy 1", new List<ProductModel>
{
new ProductModel(){ Product_Name="item1", Product_Description="Description1"},
new ProductModel(){ Product_Name="item2", Product_Description="Description2"},
}));
ObservCollectionCategory.Add(new CategoryModel("Categroy 2", new List<ProductModel>
{
new ProductModel(){ Product_Name="item1", Product_Description="Description1"},
new ProductModel(){ Product_Name="item2", Product_Description="Description2"},
new ProductModel(){ Product_Name="item3", Product_Description="Description3"},
}));
ObservCollectionCategory.Add(new CategoryModel("Categroy 3", new List<ProductModel>
{
new ProductModel(){ Product_Name="item1", Product_Description="Description1"},
new ProductModel(){ Product_Name="item2", Product_Description="Description2"},
new ProductModel(){ Product_Name="item3", Product_Description="Description3"},
new ProductModel(){ Product_Name="item4", Product_Description="Description4"},
}));
this.BindingContext = this;
}
Output:
I have to change the value in a text box dynamically, on selecting a value from a combox box, which is present in different view. when changing the dependency property's source, the propertychangedEventHandler value is not changing, i.e it is remaining as null, so the event is not getting fired. As a result the text in the textbox is not changing. Below is the code. I have bound the text in textbox to _name property.
public partial class Details : UserControl, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string name = "";
public Details()
{
InitializeComponent();
Name = Connector.Name;
DataContext = this;
}
public string Name
{
get { return name; }
set
{
name = value; OnPropertyChanged("Name");
}
}
protected void OnPropertyChanged(string s)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(s));
}
}
}
Xaml code
<StackPanel Orientation="Vertical">
<TextBlock Text="Student Details" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="16" FontWeight="Bold"> </TextBlock>
<StackPanel Margin="0,5" Orientation="Horizontal" >
<Label MinWidth="100" MaxWidth="110">Name:</Label>
<Border BorderBrush="Gray" BorderThickness="2">
<TextBox Name="nametextbox" Text="{Binding Name,Mode=TwoWay}" Width="auto" MinWidth="100" FontWeight="Black"></TextBox>
</Border>
</StackPanel>
Is it possible that you accidentally exchanged name and _name, using name in XAML for the binding?
Usually you have a public property with a capitalized name, and a private field with a non-capitalized name, optionally prefixed with an underscore as you did.
So, you should have
public string Name {
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
{
private string _name = "";
Please check the following:
If you're not currently binding to name instead of _name;
Either if that is or is not the case, please fix your naming convention, because it is a source of errors, and every example you'll find follow the convention I included above.
In your XAML, you are binding "Name" property and in your code, you have created _name property. So, you need to change it to "Name" property in your code.
Just change your property as per below:
private string _name = "";
public string Name
{
get { return _name; }
set {
_name = value;
OnPropertyChanged("Name");
}
}
Try this and let me know.
I have used eventaggregator for this purpose, as we need to change the text in the text box dynamically when an event in a different view is fired. Below is the C# code of both the DropView(where we select student name from a list), and DetailsView(where we display the details). I publish events in Drop.xaml.cs and subscribe to those events in Details.xaml.cs
Drop.xaml.cs
public partial class Drop : UserControl
{
private IEventAggregator iEventAggregator;
public Drop(IEventAggregator ieventaggregator)
{
InitializeComponent();
iEventAggregator = ieventaggregator;
this.DataContext = this;
var doc = XDocument.Load("C:\\Users\\srinivasaarudra.k\\Desktop\\students.xml");
var names = doc.Descendants("Name");
foreach (var item in names)
{
droplist.Items.Add(item.Value);
}
}
public string name;
public string Naam
{
get { return name; }
set { name = value;
iEventAggregator.GetEvent<Itemselectedevent>().Publish(Naam);
}
}
public string grade;
public string Grade
{
get { return grade; }
set
{
grade = value;
iEventAggregator.GetEvent<gradeevent>().Publish(Grade);
}
}
public string dept;
public string Dept
{
get { return dept; }
set
{
dept = value;
iEventAggregator.GetEvent<deptevent>().Publish(Dept);
}
}
public static string str;
public static string Str
{
get { return str; }
set {
str = value;
}
}
private void droplist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var sel = droplist.SelectedValue;
Str=sel.ToString();
XmlDocument doc2 = new XmlDocument();
doc2.Load("C:\\Users\\srinivasaarudra.k\\Desktop\\students.xml");
var details = doc2.DocumentElement.SelectNodes("/Students/StudentDetails");
foreach (XmlNode node in details)
{
if (node.SelectSingleNode("Name").InnerText == Str)
{
Naam = node.SelectSingleNode("Name").InnerText;
Grade = node.SelectSingleNode("Grade").InnerText;
Dept = node.SelectSingleNode("Department").InnerText;
}
}
// Details det = new Details();
Details dt = new Details(iEventAggregator);
}
}
public class Itemselectedevent:Prism.Events.PubSubEvent<string>
{
}
public class gradeevent : Prism.Events.PubSubEvent<string>
{
}
public class deptevent : Prism.Events.PubSubEvent<string>
{
}
Details.xaml.cs
public partial class Details : UserControl,INotifyPropertyChanged
{
public IEventAggregator iEventAggregator;
public event PropertyChangedEventHandler PropertyChanged;
public static string name;
public static string dept;
public static string grade;
[Bindable(true)]
public string Naam
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Naam");
}
}
[Bindable(true)]
public string Grade
{
get { return grade; }
set
{
grade = value; OnPropertyChanged("Grade");
}
}
[Bindable(true)]
public string Dept
{
get { return dept; }
set
{
dept = value;
OnPropertyChanged("Dept");
}
}
public Details(IEventAggregator eventaggregator)
{
InitializeComponent();
this.iEventAggregator = eventaggregator;
iEventAggregator.GetEvent<Itemselectedevent>().Subscribe((str) => { Naam = str; });
iEventAggregator.GetEvent<gradeevent>().Subscribe((str) => { Grade = str; });
iEventAggregator.GetEvent<deptevent>().Subscribe((str) => { Dept = str; });
this.DataContext = this;
}
protected void OnPropertyChanged(string s)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(s));
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
}
I know that it's been here a million times but I don't know what's wrong in my code. I tried everything but the ComboBox is not binding SelectedItem correctly.
Here is my complete sandbox solution. You can also find it on GitHub (https://github.com/LukasNespor/ComboBoxBinding).
BindableBase.cs
public class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public virtual void RaisePropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ContactModel.cs
public class ContactModel : BindableBase
{
private int _Id;
public int Id
{
get { return _Id; }
set
{
_Id = value;
RaisePropertyChanged(nameof(Id));
}
}
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
RaisePropertyChanged(nameof(Name));
}
}
private string _Phone;
public string Phone
{
get { return _Phone; }
set
{
_Phone = value;
RaisePropertyChanged(nameof(Phone));
}
}
public override bool Equals(object obj)
{
if (obj != null || !(obj is ContactModel))
return false;
return ((ContactModel)obj).Id == this.Id;
}
public override string ToString()
{
return $"{Name} {Phone}";
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
...>
<Grid>
<ComboBox Width="200" Height="23"
SelectedItem="{Binding ViewModel.SelectedContact}" ItemsSource="{Binding ViewModel.Contacts}" />
</Grid>
MainWindows.xaml.cs
public partial class MainWindow : Window
{
public MainViewModel ViewModel { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
ViewModel = new MainViewModel();
ViewModel.SelectedContact = new ContactModel
{
Id = 2,
Name = "Some Guy",
Phone = "+123456789"
};
}
}
MainViewModel.cs
public class MainViewModel : BindableBase
{
public List<ContactModel> Contacts
{
get
{
return new List<ContactModel>
{
new ContactModel() {Id = 1, Name = "John Doe", Phone = "+166666333" },
new ContactModel() {Id = 2, Name = "Some Guy", Phone = "+123456789" }
};
}
}
private ContactModel _SelectedContact;
public ContactModel SelectedContact
{
get { return _SelectedContact; }
set
{
_SelectedContact = value;
RaisePropertyChanged(nameof(SelectedContact));
}
}
}
You need do Sync the list with the current selected item:
1.Xaml:
<ComboBox ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedContact}" IsSynchronizedWithCurrentItem="True" />
2.ViewModel:
public ObservableCollection<ContactModel> Contacts { get; set; }
public MainViewModel()
{
_model = new Model {Name = "Prop Name" };
Contacts = new ObservableCollection<ContactModel>
{
new ContactModel {Id = 1, Name = "John Doe", Phone = "+166666333"},
new ContactModel {Id = 2, Name = "Some Guy", Phone = "+123456789"}
};
SelectedContact = Contacts[0];
}
private ContactModel _SelectedContact;
public ContactModel SelectedContact
{
get { return _SelectedContact; }
set
{
_SelectedContact = value;
OnPropertyChanged(nameof(SelectedContact));
}
}
based on this Post post link,I am having problem in modifying the Background of a Button and the images according to the values that I have get from a Web Service:
this is what I did:MainPage.cs:
ObservableCollection<Item> Locals = new ObservableCollection<Item>();
public async void getListePerSearch()
{
try
{
UriString2 = "URL";
var http = new HttpClient();
http.MaxResponseContentBufferSize = Int32.MaxValue;
var response = await http.GetStringAsync(UriString2);
var rootObject1 = JsonConvert.DeserializeObject<NvBarberry.Models.RootObject>(response);
foreach (var item in rootObject1.locals)
{
Item listItem = new Item();
if (item.fav == 1)
{
listItem.ButtonColor= new SolidColorBrush(Colors.Yellow); //Yellow
}
else
{
listItem.ButtonColor= new SolidColorBrush(Colors.Gray);//Gray
}
if (item.aime == 1)
{
listItem.MyUrl2 = new Uri("ms-appx:///images/coueur_rouge.png", UriKind.Absolute);
}
else
{
listItem.MyUrl2 = new Uri("ms-appx:///images/like.png", UriKind.Absolute);
}
if (item.aimepas == 1)
{
listItem.MyUrl1 = new Uri("ms-appx:///images/icon_cer_selected.png", UriKind.Absolute);
}
else
{
listItem.MyUrl1 = new Uri("ms-appx:///images/icon_cer.png", UriKind.Absolute);
}
Locals.Add(listItem);
}
listme.ItemsSource = Locals;//I get 4 Items here
}
and this is Item.cs:
public class Item : INotifyPropertyChanged
{
private Uri myUrl1;
public Uri MyUrl1
{
get { return myUrl1; }
set
{
myUrl1 = value;
NotifyPropertyChanged("MyUrl1");
}
}
private Uri myUrl2;
public Uri MyUrl2
{
get { return myUrl2; }
set
{
myUrl2 = value;
NotifyPropertyChanged("MyUrl2");
}
}
private SolidColorBrush buttonColor = new SolidColorBrush(Colors.Gray);
public SolidColorBrush ButtonColor
{
get { return buttonColor; }
set
{
buttonColor = value;
NotifyPropertyChanged("ButtonColor");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
Locals.cs:
public class Locals
{
public int fav { get; set; }
public int aime { get; set; }
public int aimepas { get; set; }
}
and finally this is the xaml :
<ListView x:Name="listme">
<ListView.ItemTemplate >
<DataTemplate >
<Grid>
...
<Button Background="{Binding ButtonColor} Tapped="Button_Tapped"/>
<Image Source="{Binding MyUrl2}"/>
<Image Source="{Binding MyUrl1}"/>
</Grid>
</DataTemplate >
</ListView.ItemTemplate >
</ListView >
I get as a result 4 items in the ListView not 2 as you can see in the json data,the modification does not apply on each ListViewItem
did I make a mistake in my code??How can I correct my code to get only the 2 Items and assign an image and a Background Color according to the web Service values for each ListviewItem
this is the result of Debugging:
thanks for help
Update:rootObject1.locals: