TextBlock not showing up in ListView - c#

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();
}

Related

WPF C# add text and image to ComboBox during runtime

Basically, when a user clicks a button I would like to add a list of the names of the currently running applications with their icon next to them within a ComboBox. I know how to get my list of applications and my icons but am unsure how to link everything together. My XAML for the ComboBox currently looks like the following:
<ComboBox x:Name="dial1AppSelection" Grid.Column="3" Grid.Row="4" MinHeight="25" Height ="25" MaxHeight="35" MinWidth="120" Margin="4,0,0,0" SelectionChanged="dial1AppSelection_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="20" Source="???" />
<TextBlock ><Run Text="???" /></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Add to your combobox
ItemsSource="{Binding YourCollection}"
Create class for your objects:
public class MyProcess
{
public ImageSource Image { get; set; }
public string Text { get; set; }
}
Add such code to your MainWindow.xaml.cs
public ObservableCollection<MyProcess> YourCollection { get; set; }
public MainWindow()
{
InitializeComponent();
YourCollection = new ObservableCollection<MyProcess>();
YourCollection.Add(new MyProcess() { Image ="image1", Text = "txt1"});
DataContext = this;
}
Insert fields names to your xaml code:
Source="{Binding Path=Image}"
Text="{Binding Path=Text}"

binding to a static list and properties xamarin forms

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>

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.

MVVM + multilevel/nested databinding

The Structure
The scenario is that I have a Pivot where each item is the menu of a certain day. Inside that PivotItem I need to display the dishes on the menu, grouped by category (e.g. soups, desserts, ...).
I have implemented this with the MVVM-model.
I thus have the folowing models:
public class Menu{
public string Date;
public List<DishList> Categories;
}
public class DishList
{
public string Category;
public List<Dish> Dishes;
}
public class Dish
{
public string Name;
public string Price;
}
Edit: these are simplified here, the actual structure for each field is like this:
private string _date;
//Get_Set
public string Date
{
get
{
return _date;
}
set
{
if (value != _date)
{
_date = value;
}
}
}
So the structure would be like this: a PivotElement containt a Menu-object. Inside it, I show Categories, a number of DishLists. Inside that Dishlist, I show the Category and the different Dishes, each with it's Name and Price. A mockup to make things a bit more clear (pdf-file on SkyDrive); http://sdrv.ms/12IKlWd
I have the following viewmodel
public class MenuViewModel : INotifyPropertyChanged
{
private ObservableCollection<Menu> _Menus;
}
The view that should implement (the structure) of the desired layout is as following:
<phone:Pivot
ItemsSource="{Binding Menus}">
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Date}" />
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<ItemsControl
ItemsSource="{Binding Categories}">
<TextBlock
Text="{Binding Category}"/>
<ItemsControl
x:Name="Dishes"
ItemsSource="{Binding Dishes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="1"
Text="{Binding Name}"/>
<TextBlock
Grid.Column="2"
Text="{Binding Price}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ItemsControl>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
As you can see, there's nested databinding to get to the data it needs.
The only code I then do on the page is
DataContext = App.ViewModel;
The Problem
When I launch it up, I get the correct Data displayed in the PivotItems header, and the correct number of PivotItems. Ufortunately, that's it; the content of the PivotItem stays empty. The first level of databinding thus works, but no further.
The way I was thinking
1st level: each PivotItem is linked to an object of type Menu, with header Menu.Date
2nd level: Inside that PivotItem I set the ItemsSource of a ItemsControl to that Menu.Categories
3rd level : The ItemsSource now is Menu.Categories.Dishes
I have already searched quite a bit and fiddled around with Datacontext and ItemsSource and different kinds of "{Binding ...}", but I can't get it to work. I would like to do the binding in xaml, and not in the code-behind.
Notes
The only function is to display data. The data is stationary and loaded once from a file.
That's why I chose ItemsControl instead of ListBox, there is no need to select anything.
This is a MVVM-approach to my previous question: Databinding + Dynamic Pivot
First off, you're trying to access a private field in the title so that won't work. These also have to be properties, not fields.
<TextBlock Text="{Binding Date}" />
private string Date;
Next you're binding to Category, which is also private and not a property.
<TextBlock Text="{Binding Category}"/>
private string Category;
And you're binding to the Categories field which needs to be a property.
<ItemsControl ItemsSource="{Binding Categories}">
public List<DishList> Categories;
Even if you correct these issues, you still won't get what you want because your outer ItemsControl doesn't have an ItemTemplate.
<ItemsControl ItemsSource="{Binding Categories}">
<TextBlock Text="{Binding Category}"/>
...
</ItemsControl>
Added: Your new error is because the DataTemplate can only have one child element so you need to use a container like a StackPanel.
<ItemsControl ItemsSource="{Binding Categories}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Category}"/>
<ItemsControl x:Name="Dishes" ItemsSource="{Binding Dishes}">
...
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Categories