Silverlight: How to use a converter with an ItemsControl? - silverlight

I have an ItemsControl whose ItemsSource is bound to a list of ints IDs. A converter uses the IDs to look up the name that should be displayed to the user. How can I do this in XAML? Here is what I have so far, but it doesn't work:
<ItemsControl ItemsSource="{Binding Topics}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FallbackValue='topic name', Converter={StaticResource topicToStrConverter}}" Margin="0,10,0,0"/>
<Button>
<Image Source="/PlumPudding;component/Images/appbar.cancel.rest.png" />
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Really, what I want as an argument to the converter is the entire item that is being displayed in the template - not a property of that item. What is the syntax for this?
I'm using Silverlight 4.

if Topics is List, then what you have is correct.
However, if Topics is List, and Id is a property of the Topic class, you will need to use "Path=Id". So: {Binding FallbakcValue='Bla', Path=Id, Converter={StaticResource yourConverter}
To answer you second question:
"what I want as an argument to the converter is the entire item that is being displayed in the template - not a property of that item"
This syntax you are using will pass the entire object in the List, so in your case an int is passed to the converter. Again, if it is a list, then the Topic object is passed to the converter.

Your code is right to my opinion..
It seems that problem in 'converter'. Try to debug code of topicToStrConverter.

You have to set the DataContext for the items control or for one of it's parents. If you don't do this there is no context for the binding.

Related

Change DataTemplate textblock Visibility determined by parent container type

I have a <DataTemplate> as defined below, which contains a <TextBlock>
The <DataTemplate> is used in several instances of a <ListBox> and reused elsewhere in a <ContentControl>
Note code simplified for brevity
<DataTemplate x:Key="SetsItemTemplate" DataType="viewModel:SetVm">
<TextBlock
Visibility="{Binding <somethign here i guess>,
ConverterParameter=collapse,
Converter={StaticResource BoolToVisConverter}}">
</TextBlock>
</DataTemplate>
<ListBox ItemTemplate="{StaticResource SetsItemTemplate}" />
<ContentControl ContentTemplate="{StaticResource SetsItemTemplate}" />
The <TextBlock> has a boolToVisibility Converter to collapse the <TextBlock> on a condition, however i really need that condition to check if the parent container is a <ContentControl>
I.e If the <DataTemplate> parent is a <ContentControl> collapse the <TextBlock>
Maybe i could use Names to make this easier (i'm not sure)
In order to access the parent, you need to get the sender or the source object. There is no way you can get this using IValueConverter. But, they already have a solution for this:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/9f3e4f6d-20d2-4c13-90a2-7c157ed4f8c3/ivalueconverter-pass-calling-object-as-converterparameter?forum=wpf
Now, you can access the element and get the parent through:
element = VisualTreeHelper.GetParent(element) as UIElement;
Hope it helps!
You can change the visibility based on the parent element as mentioned in the above msdn link. you can achieve this by using parent element name property with BoolToVisibilityConverter. Like bind the element name to TextBlock Visibility property with converter and define the visibility in converter based on the bounded ElementNameProperty.

Consuming Complex Comboboxes WPF

I want to have complex combobox with checkboxes, text, and may be a thumbnail. I have already looked at the following links which helped me alot while building complex comboboxes.
http://blogs.microsoft.co.il/blogs/justguy/archive/2009/01/19/wpf-combobox-with-checkboxes-as-items-it-will-even-update-on-the-fly.aspx
Looking for a WPF ComboBox with checkboxes
But, I can not find a way to consume these complex usercontol in my application. I am new to WPF, so any kind of demonstration support would be highly appreciated.
Dean, I was looking a solution of how to bind in code behind file with following example mentioned in an SO post earlier.
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Width="20" />
<TextBlock Text="{Binding DayOfWeek}"
Width="100" />
</StackPanel>
</DataTemplate>
So the question is, Do I need DataTable or something else to bind my list of Checkboxes and Titles with this combobox template?
Thanks in Advance
A Combobox is an ItemsControl. All ItemsControls can be filled "hardcoded" with items or containers.
This adds a new entry in the combobox, and wrappes the string into an ItemsContainer, which is a ComboBoxItem.
<ComboBox>
<sys:string>Hello</string>
<ComboBox>
Here we create a combobox item directly, and add its content to a string with the value "Hello"
<ComboBox>
<ComboBoxItem Content="Hello"/>
<ComboBox>
Both look visually the same. Its important to understand that in the first case the ComboBox takes care of wrapping our, to the ComboBox unknown type string, into an ComboBoxItem, and uses a default DataTemplate to display it. The default DataTemplate will display a TextBlock and calls ToString() on the given data item.
Now to have dynamic data, we need a ObservableCollection with our data items.
class Employee
{
public BitmapSource Picture {get;set;}
public string Name{get;set}
}
ObservableCollection<Employee> employees;
myComboBox.ItemsSource = employees;
We have a DataClass called Employee, an observable Collection which holds many of our dataitem, and set this collection as the ItemsSource. From this point on, our Combobox listens to changes to this collection. Like adding and removing Employees and automatically takes care of wrapping the new Employee into a ComboBoxItem. Everything is done automatically. The only thing we need to do is to provide a proper DataTemplate. The combobox doesn't know how to "display" an employee and thats exactly what a DataTemplate is for.
<DataTemplate x:Key="employeeTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Picture}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
We know an employee is wrapped in a ComboBoxItem, and the ComboBoxItem uses a provided Datatemplate to display its data, which means that inside the DataTemplate we can use Binding to access all properties on the data item.
Hope that helps you.
to just answer your question. all you need is a collection of an object with at least 2 public properties (IsSelected as bool and DayOfWeek as string) and just set these collection as the itemssource.
so all you need is a collection of such an object. just comment if you need an example.
ps: pls read through the www for wpf and binding to get the basics.
you could simple add the items directly
<ComboBox>
<ComboBox.Items>
<ComboBoxItem>
<TextBlock Text="test text" />
</ComboBoxItem>
<ComboBoxItem>
<CheckBox Content="test checkbox" />
</ComboBoxItem>
<ComboBoxItem>
<Button Content="test button" />
</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
or if you want to use ItemsSource, the a DataTemplateSelector would be required
<ComboBox>
<ComboBox.ItemTemplateSelector>
<local:MyCustomTemplateSelector />
</ComboBox.ItemTemplateSelector>
</ComboBox>
here is a link that explains DataTemplateSelectors
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplateselector.aspx

wpf binding text to parent listbox's contents

I have a listBox whose items are to be shown in a textbox format, like so:-
<ListBox ItemsSource="{Binding movieList}" Name="innerList">
<ListBox.ItemTemplate >
<DataTemplate >
<TextBox Text="-------" TextChanged="TextBox_TextChanged_1"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
EDIT:
Sorry, movie list was an observablecollection (of Movie) instead of being (of String)
How do I get the textbox to show the contents of its ancestor (the innerList) ?
If you want to display the title of a movie in the TextBox, just use that:
<TextBox Text="{Binding Title}" TextChanged="TextBox_TextChanged_1"/>
(assuming the items in the list are objects with a Title property)
From Binding Declarations Overview
Optionally, a period (.) path can be used to bind to the current
source. For example, Text="{Binding}" is equivalent to Text="{Binding
Path=.}".
So following should do it.
<TextBox Text="{Binding}" TextChanged="TextBox_TextChanged_1"/>

WPF ListBox ItemsSource with DataTemplate

I have a ListBox with an ItemsSource pointing to a static variable, and a DataTemplate for the ListBox's ItemTemplate that should be displaying the Description property of the variable the ItemsSource points to
<ListBox x:Name="classificationTypeListBox"
ItemsSource="{x:Static h:AmbientHighlightingStyleRegistry.Instance}"
SelectedIndex="0" Foreground="Black">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=(Description)}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I can put a break point on my application and view the ListBox. The ItemsSource does point to the variable I want and it looks like the ListBox is trying to display all the values because I can click and scroll down the it. However, no text is getting displayed so you can't actually tell what you're clicking. Also, while the break point is on, it says that the list box contains 0 items, maybe it should because I'm binding it, not sure. Any suggestions?
<TextBlock Text="{Binding Path=(Description)}" />
Why do you have parens in there? This syntax causes WPF to try to bind to an attached property, which is not what you want to do.

Is there a way to databind to a list of doubles for editing in WPF?

I have a list of doubles which I need to display. The user can remove elements, add elements, or change the elements. Right now I am making text boxes and buttons in a for loop. Is there a quickier way to do this with databinding?
WPF VS2010 2010 C#
Additionally to what Brady said you probably want to wrap your doubles in a class, doubles are primitive types and hence if you have a collection of them they are not guaranteed to be unique so i'd bind to a ObservableCollection<DoubleWrapper> with DoubleWrapper only containing one property Value of type double.
You can use an ItemsControl or a control that inherits from it. All you need is a DataTemplate.
<ItemsControl ItemsSource="{Binding Path=MyDoublesList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Command="{Binding MyButtonCommand}" />
<TextBox Text="{Binding Path=Description}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
There is a good overview on MSDN.
http://msdn.microsoft.com/en-us/library/ms742521.aspx

Resources