Binding data to ListView doesn't work (Metro UI) - c#

When I put this code into my XAML file:
<TextBlock Text="{Binding Name}" FontSize="16" Margin="15,0,0,0" />
It shows me Name value but when I try show it via ListView:
<ListView x:Name="ItemListView"
ItemsSource="{Binding Items}"
Margin="60,0,0,10">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"
FontSize="24" Margin="5,0,0,0" TextWrapping="Wrap" />
<TextBlock Text="{Binding Artist}"
FontSize="16" Margin="15,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It doesn't show up :( What could be wrong?

If the page inherits from LayoutAwarePage, like it will by default when created from a template, the DataContext will be set to a property named DefaultViewModel. Properties exposed in your codebehind will not be bound to.

You are looking at two different objects in the sample. In the textbox you are looking at the Name of the object in the datacontext, in the listview you are looking at the Items[x].Name for each item you bind to. If you need to reference the Name from the datacontext rather than the Items collection you will need to bind the source to an Element not inherit it.

Related

Can a user control perform binding when part of a ListView in WinUI?

I'm trying to use a UserControl-derived control (UpdateBlockControl) inside the DataTemplate of a ListView, like this:
<ListView x:Name="AppsListView">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:AppBase">
<StackPanel Orientation="Horizontal">
<local:UpdateBlockControl ImageSource="{x:Bind ImageSource}" AppName="{x:Bind Name}"/>
<TextBlock Text="{x:Bind Name}" Foreground="Orange" Margin="8,0,0,0" />
<TextBlock Text="{x:Bind ImageSource}" Margin="8,0,0,0" Foreground="LimeGreen"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
UpdateBlockControl is derived from UserControl and I'm trying to bind its properties (ImageSource and AppName) to the model's (AppBase) properties.
You can see me trying to set up these bindings in the first item in the StackPanel. Just to see if the binding works at all, I also bind a couple of TextBlocks to these properties.
The XAML for UserBlockControl is essentially this:
<StackPanel Orientation="Vertical">
<TextBlock Text=":-)"/>
<TextBlock Text="{x:Bind AppName}"/>
<TextBlock Text="{x:Bind ImageSource}"/>
</StackPanel>
When I run the application I see the following:
So the UserControl properties aren't working correctly it would seem: I get the :-) for the first TextBlock but the second and third TextBlocks are empty. Their equivalents in the ListView do work however (see image, above).
Should I be able to use a user control insisde a DataTemplate like this? If so, why aren't the bindings working?
x:Bind is Mode=OneTime by default. So, once a DependencyProperty is initialized inside the UserControl, it won't be updated anymore.
You need to add Mode=OneWay to x:Bind in UpdateBlockControl.
<StackPanel Orientation="Vertical">
<TextBlock Text=":-)" />
<TextBlock Text="{x:Bind AppName, Mode=OneWay}" />
<TextBlock Text="{x:Bind ImageSource, Mode=OneWay}" />
</StackPanel>

How to nest ItemsControl with multiple ItemsSource?

I have a ConfigList object with a name and a Dictionary and I need to nest ItemsControls with different ItemsSource.
I tried to do it this way :
<ItemsControl x:Name="TestStep" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=ConfigList }" HorizontalAlignment="Center" VerticalAlignment="Center">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Ictrl.Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl
ItemsSource="{Binding Path=Param}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Key}" />
<TextBlock Text=" : " />
<TextBlock Text="{Binding Path=Value}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ItemsControl>
When I start my application, I've got this error :
System.Windows.Markup.XamlParseException : '' Adding a value to the
collection of type 'System.Windows.Controls.ItemCollection' threw an
exception. ' line number '25' and line position '14'. '
Internal Exception
InvalidOperationException: Invalid operation when ItemsSource is in
use. Access and edit items with ItemsControl.ItemsSource.
Any idea what ​​the problem is?
You set an ItemsSource on the ItemsControl. The data template is used to create the controls that display the data. The created items are then put into the Items collection of the ItemsControl. If you add an element to the ItemsControl directly in XAML this will put them into the Items collection, too. Doing both is not allowed. You either specify an ItemsSource or add to Items directly. From the documentation:
Note that you use either the Items or the ItemsSource property to specify the collection that should be used to generate the content of your ItemsControl. When the ItemsSource property is set, the Items collection is made read-only and fixed-size.
However, in your case this is not the real issue, because your markup is wrong for what you want to achieve. If you you really intended to nest ItemsControls, you would simply change the data template for the outer ItemsControl to contain another ItemsControl that binds to a collection property within the outer data item. Since there is already a TextBox, you have to use a panel (e.g. StackPanel) to host multiple controls in the template.
<ItemsControl x:Name="TestStep" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=ConfigList }" HorizontalAlignment="Center" VerticalAlignment="Center">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Ictrl.Nom}" />
<ItemsControl ItemsSource="{Binding Path=Param}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Key}" />
<TextBlock Text=" : " />
<TextBlock Text="{Binding Path=Value}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If you want to have a hierarchical view of your data, using a TreeView might be a better fit.

I am using WPF and I have DataTemplate that is i want to access into the codebehind how I can use this?

I am using WPF and I have DataTemplate that is i want to access into the codebehind how I can use this?
<DataTemplate x:Name="PersonDateTemplate">
<StackPanel Orientation="Horizontal">
<Label x:Name="lblhr" Height="40px" Width="50px"
Content="{Binding Path=hrvalueinitially}" FontSize="20px"
HorizontalAlignment="Left" Background="#555555" Foreground="White"
FlowDirection="LeftToRight"></Label>
<TextBlock x:Name="items" Text="{Binding}" Margin="35,0,0,0"></TextBlock>
</StackPanel>
</DataTemplate>
If you are having the DataTemplate in Resource and you have Key defined, you can access the resource in CodeBehind as follows,
DataTemplate dataTemplate = App.Current.TryFindResource("PersonDateTemplate") as DataTemplate;
or if you want create from scratch in CodeBehind, you should use FrameworkElementFactory
You can use dataTemplate to replace the visual appearance of a data item in a control like ListBox, ComboBox or ListView.
To understand how to work with dataTemplate I've done the following example:
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ID}" FontSize="24"/>
<TextBlock Text=". Name: " FontSize="24"/>
<TextBlock Text="{Binding Name}" FontSize="24"/>
<TextBlock Text=" ,Age: " FontSize="24"/>
<TextBlock Text="{Binding Age}" FontSize="24"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
For better understanding about the data template you may follow the following link:
https://msdn.microsoft.com/en-us/library/ms742521(v=vs.110).aspx

How to bind properties of one ObservableCollection of ListView to properties of SelectedItem of another ListView?

So I have a few ListViews. The first is binded to ObservaleCollection<ComPort>. All properties of ComPort may take some predefined values. Other ListViews are responsible for that properties: they show all that possible (predefined) values and SelectedItem should be the current value of that property of ComPort from the first ObservaleCollection.
I can't attach images so here is an external picture, it would make the situation clean: http://i.stack.imgur.com/ZBRRx.png
<Window.Resources>
<ResourceDictionary x:Name="rd">
<l:ComPorts x:Key="vComPorts"/>
<l:SystemPorts x:Key="vSystemPorts"/>
<l:BaudRates x:Key="vBaudRate"/>
<l:Parities x:Key="vParities"/>
<l:DataBits x:Key="vDataBits"/>
<l:StopBits x:Key="vStopBits"/>
<l:Timeouts x:Key="vTimeouts"/>
<l:ComPort x:Key="vSelectedPort"/>
</ResourceDictionary>
</Window.Resources>
...
<ListView
Name="PortsList"
Grid.Row="1"
Grid.Column="0"
Margin="5"
VerticalAlignment="Stretch"
ItemsSource="{StaticResource vComPorts}"
DataContext="{StaticResource vComPorts}"
SelectedValuePath="PortName"
SelectedValue="{Binding ElementName=SystemPortsList, Path=SelectedItem.Value}"
SelectionChanged="PortsList_SelectionChanged"
MouseDoubleClick="PortsList_MouseDoubleClick">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox />
<TextBlock Margin="5,0,0,0" Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView
x:Name="SystemPortsList"
Margin="5"
VerticalAlignment="Stretch"
DataContext="{Binding Source={StaticResource vSelectedPort}}"
ItemsSource="{Binding Source={StaticResource vSystemPortsView}}"
SelectedItem="{Binding Source={StaticResource vSelectedPort}, Path=PortName}"
MouseEnter="SystemPortsList_Refresh"
MouseLeave="SystemPortsList_Refresh"
Grid.Row="1"
Grid.Column="1" SelectionChanged="SystemPortsList_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="tb" Margin="5,0,0,0" Text="{Binding Path=Name}" />
</StackPanel>
</ListView.ItemTemplate>
</ListView>
I've tried to make an instance of class ComPort for saving current value of selected item from the first ListView, but anyway I can't cope with it without help. How this task should be solved?
1) Instead of handling SelectionChanged on the PortsList ListView, bind your checkbox to the ListViewItemsPanel like so:
<CheckBox IsChecked={Binding IsSelected, RelativeSource=Parent/>
2) Add an x:Name to your first ListBox, say x:Name="ComPortLB";
3) Remove DataContext on SystemPortsList;
4) Fix SelectedItem on SystemPortsList like so:
SelectedValue="{Binding ElementName=ComPortLB, Path=SelectedValue.PortName}"
I haven't tested any of this code and I haven't done this kind of stuff for a while, so I apologize for errors, but it should get you closer. I've also had to make some assumptions about your classes since you don't provide enough information.

Windows 8 store app: How dynamically change Binding in ListViewItem

I have created a common control for listView and I want to change the content of each item in the listView. Something like DisplayMemberPath but I need to send two values ​​that are not the same for any one screen.
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Property1}"/>
<TextBlock Text="{Binding Setter2}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
and on the next screen I want something like this
<TextBlock Text="{Binding SuperNewProperty}"/>
<TextBlock Text="{Binding Setter2xyz}"/>
How do I create a control which has variable binding like:
<TextBlock Text="{Binding {Binding MySpecificValue}"/>
This is obviously a stupid thing, but it best describes what I want to do.
For completion:
Ok i have some module Employes.xaml
where call, my control with some dependency properties as itemSource and prop1, prop2(I want to use both, like display member path).
ItemSource is IEnumerable from DB and contains 2 columns: employeName, employNumber, this will be displayed on the listView
<control:listViewMyControl itemSource ="{Binding employes}" prop1="employeName" prop2="employNumber" />
but when i have modul Cities.xaml
I need binding prop1, prop2 to another column name, cityName, cityRank or whatever
<control:listViewMyControl itemSource ="{Binding cities}" prop1="cityName" prop2="cityRank " />
The problem comes when I want to display two different types of listviewitems for listview
// my user control listViewMyControl
<ListView x:Name="listView1">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding employeName}"/>
<TextBlock Text="{Binding employeNumber}"/>
<TextBlock Text="{Binding cityName}"/>
<TextBlock Text="{Binding cityRank}"/>
// but i want only something like display member path for two labels, input modules may be more (employes, cities, cars, stations, .....) something like this
<TextBlock Text="{Binding {Binding MySpecificValue}"/>
<TextBlock Text="{Binding {Binding MySpecificValue2}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Thanks in advance.

Categories