binding to a static list and properties xamarin forms - c#

I am making a portable Xamarin project. I have the following List in the class Stash:
public class Stash
{
public static List<Group> Groups { get; set; }
}
and a class Group:
public class Group
{
[JsonProperty(PropertyName ="Name")]
public string Name { get; set; }
[Newtonsoft.Json.JsonProperty("Id")]
public string GroupId { get; set; }
}
In another page in XAML I want to bind to a static list. I have a ListView that I want to bind to the Group List:
<ListView ItemsSource="{Binding Source={x:Static local:Stash.Groups}}"
IsGroupingEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" TextColor="Black"
Detail="{Binding GroupId}" DetailColor="Aqua">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I defined the Namespace in the local in XAML:
xmlns:local="clr-namespace:Namespace"
My List is filled from the Sql Azure Database so it is not empty guys , Can anybody tell me what is wrong with my code? I cant seem to display the list on my screen , All what is displayed is this sentence Namespace.Group .

The following binding is incorrect. You don't need to
<ListView ItemsSource="{Binding Source={x:Static local:Stash.Groups}}"
You should change this to
<ListView ItemsSource="{Binding {x:Static local:Stash.Groups}"
Databinding Xamarin ListView

its working , i just removed IsGroupingEnabled="true" and it worked
<ListView ItemsSource="{Binding Source={x:Static local:Stash.Groups}}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" TextColor="Black"
Detail="{Binding GroupId}" DetailColor="Aqua">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>

Related

TextBlock not showing up in ListView

This is my ListView:
<ListView ItemsSource="{Binding ModuleList}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<Image Source="{Binding ModuleImage}" Stretch="UniformToFill"/>-->
<TextBlock Text="{Binding ModuleName}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is the code in WPF (MVVM):
public ItemListViewVM() : base()
{
ModuleList = new List<Module>();
modulLoader.LoadAllModules();
tempModulList = modulLoader.GetAllModules();
foreach (var module in tempModulList)
{
ModuleImage = module.ModuleImage;
ModuleName = module.Name;
ModuleList.Add(module);
}
}
Long story short: The List tempModulList contains Objects of type Module, which has an ImageSource Image and a string Name. Then the ModuleList gets one item after another. When I uncomment the Image in xaml, you can see it. But the TextBlock won't show up no matter what. I checked the string module.Namefor every item, it is not empty.
EDIT: Add Module Class
The Module Class just contains Name and Image:
public class Module
{
public ImageSource ModuleImage { get; set; }
public string Name { get; set; }
}
The Object gets created by deserializing a Json
The Bindings in the ItemTemplate use the properties of the data item class as their source properties. Hence you should write
Text="{Binding Name}"
instead of
Text="{Binding ModuleName}"
Unless you set the View property of a ListView (to e.g. a GridView) you could also better use a ListBox, which is the base class of ListView, and simpler:
<ListBox ItemsSource="{Binding ModuleList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ModuleImage}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Initializing the ModuleList property in the view model constructor would be as simple as this:
public ItemListViewVM()
{
modulLoader.LoadAllModules();
ModuleList = modulLoader.GetAllModules();
}

How to multiple value in BindingContext in xamarin ContentPage

I have xamarin application where I need to pass two objects to .cs file on button click event.
I have two ListView and have button in inside the 2nd Listview items. Both ListViews will be loaded dynamically based on the JSON. Now the problem is I need to send Parent ListView datasource and second ListView data source in the button click event. currently I am able to send only one using BindingContext but I need to send two or more objects to .cs file.
<ListView x:Name="StaffListMaster_List" RowHeight="150">
<ListView.ItemTemplate>`
<ListView x:Name="Staff_Record" ItemsSource="{Binding Path=detailsobj}">`
<ListView.ItemTemplate>`
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" >
<Button Clicked="OnActionSheetCancelDeleteClicked" BorderRadius="0" BindingContext ="{Binding item}" Text="{Binding item[6]}"/>`
I want to get StaffListMaster_List data source and Staff_Record datasource inside
OnActionSheetCancelDeleteClicked(object sender, EventArgs e) {}`
First of all, don't do that. that's not what BindingContexts are for, secondly if you are responding to the event on your code behind you could just access both the DataSources using the ListView's name i.e. Staff_Record.ItemSource
If you want to use a nested Listview inside Listview, we could do that with ListView.GroupHeaderTemplate.
ParentItems class:
public class ParentItems : ObservableCollection<ChildItems>
{
public string ID { get; set; }
public string Title { get; set; }
public ParentItems(List<ChildItems> list) : base(list)
{
}
}
ChilsItems class:
public class ChildItems
{
public string ChildTitle { get; set; }
public string Description { get; set; }
}
Xaml:
<ListView HasUnevenRows="True" x:Name="listView" IsGroupingEnabled = "True">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell Height="40">
<StackLayout Orientation="Horizontal"
BackgroundColor="#3498DB"
VerticalOptions="FillAndExpand">
<Label Text="{Binding ID}"
VerticalOptions="Center" />
<Label Text=" "/>
<Label Text="{Binding Title}"
VerticalOptions="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding ChildTitle}" Detail="{Binding Description}"></TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Result:
I have uploaded on GitHub, you could download ListViewBindng folder for reference on GitHub.
https://github.com/WendyZang/Test
Finally I am able to solve the issue as follows :
Step 1 : Create IMultiValueConverter interface
Step 2 : created MultiBinding.cs class (ref : [https://gist.github.com/Keboo/0d6e42028ea9e4256715][1] )
Step 3 : Include xmlns:multi="clr-namespace:MultiBindingExample" namespace
step 4 :
<Button Command="{Binding ClearListItem}">
<Button.CommandParameter>
<multi:MultiBinding >
<Binding Source="{x:Reference control1}" Path="BindingContext"/>
<Binding Source="{x:Reference control2}" Path="BindingContext"/>
</Button.CommandParameter>
</Button>
step 4 : In view model
void ClearListViewSelectedItem( object param)
{
var commandParamList = (object[])param;
}
Final expected result would be.

WPF Binding on Nested ItemControls with Sub Collection

I have the following xaml:
<ItemsControl ItemsSource="{Binding ResearchLanguageViewModel.Filters, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Type}"></TextBlock>
<TextBox Text="Search...."></TextBox>
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=Values}"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
With the following objects/collection(s):
public class FilterViewModel
{
public string Type { get; set; }
public ObservableCollection<string> Values { get; set; }
}
public class ResearchLanguageViewModel
{
public int FirmCount { get; set; }
public ObservableCollection<FilterViewModel> Filters { get; set; }
}
I'm trying to bind on the Filters property and the Type property comes out fine. However, I am having trouble getting the Values collection of strings to show as a group of checkboxes. Not sure what I'm doing wrong here...
Values in your View Model is an array, and you are trying (I'm assuming) to create an array of Checkboxes with the values of each checkbox being the index value into that array.
In your model, you are passing in the array of values into the content of one single checkbox control. What you need to do is bind the array to the parent's ItemsSource and bind the new value to the Checkbox control's content. Something like this:
<ItemsControl ItemsSource="{Binding ResearchLanguageViewModel.Filters, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Type}"></TextBlock>
<TextBox Text="Search...."></TextBox>
<ItemsControl>
<ItemsControl.ItemTemplate ItemsSource={Binding Path=Values}>
<DataTemplate>
<CheckBox Content="{Binding Mode=TwoWay}"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Bind your item controls, ItemSource property to values.
For a string, you won't even need a template. In your model, you have a collection of strings, so binding to a checkbox template does provide some UI enhancement but my betting is you want the checked status represented in the view model too.
You might want to consider creating an object to encapsulate your label and Checked status and defining your collection based on that.
public class CheckModel
{
public string Label {get; set;}
public bool Checked { get; set; }
}
Then bind your checkbox to:
<CheckBox IsChecked="{Binding Checked}" Content="{Binding Label}" />
I hope this helps.
You will want to bind Values to the ItemsControl not the Checkbox,
<StackPanel>
<TextBlock Text="{Binding Path=Type}"></TextBlock>
<TextBox Text="Search...."></TextBox>
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>

Bounded element's ItemsSource is not updated in view

I have a simple ListView What is bound to an object's (TaxonDescription) list.
When I select another TaxonDescription, then the ListView's element are doesnt updated.
Maybe I need somewhere the NotifyPropertyChanged, but i tried everywhere.
There are my classes.
At the page's codebehind I check the ItemSource, and it is have the right list element, just dont updated to the View.
<ListView ItemsSource="{Binding Descriptions}"
SelectedItem="{Binding ActualSelectedDescription, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DescriptionName}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
// this not updated
<ListView ItemsSource="{Binding ActualSelectedDescription.Images}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding NormalUri}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Text="{Binding ActualSelectedDescription.Name}"/> //This is works well
The ActualSelectedDescription is changed by an event.
public TaxonDescription ActualSelectedDescription
{
get{return actualSelectedDescription;}
set { actualSelectedDescription = value;
RaisePropertyChanged("ActualSelectedDescription"); }
//In the setter the Images are in the list
}
And there is the list element in the Images list
There is the Description class, with the list.
class TaxonDescription
{
public List<BaseImage> Images { get; private set; }
public string Name { get; private set; }
public TaxonDescription(string taxonName, string descriptionName)
{
Name = taxonName;
Images = new List<BaseImage>();
//Adding some element
}
}
Any accurate idea can help, i will try them all ;)
ActualSelectedDescription.Images has no change notification.
Try adding notification for Images property.
If that's not possible, make Images an ObservableCollection<BaseImage>.
If that's an issue, try setting data context to a notifying property:
// this should start updating
<ListView DataContext="{Binding ActualSelectedDescription}"
ItemsSource="{Binding Images}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding NormalUri}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
EDIT:
Just noticed that TaxonDescription is not public - is that a typo here in SO or is the class private in your actual code?
Since if it's private, the ItemsSource="{Binding ActualSelectedDescription.Images}" will not work since there's no access to Images property.

How to bind a IEnumerable<string> to a ListBox?

This may be a very simple question, but at the moment I don't actually know what to google.
If I had an object like this:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In my VM I have a list of employees (public List<Employee> Employees). It's easy to bind this in my Xaml to a ListBox:
<ListBox ItemsSource={Binding Employees}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But what if my list of employees would contain strings and not Employee objects? How could I bind these string values to the TextBlock in the data template?
Just write {Binding} where you specify the binding.

Categories