How to Bind with a StringFormat - wpf

I have a ComboBox which I am binding to an IEnumerable<int> source.
The source has values like 12,13,14 but I want the ComboBox to display Version 12, Version 13, Version 14 etc with SelectedValue still 12, 13 and 14.
For now I am modifying the Source to add Version to it and then Binding the ComboBox to an IEnumerable.
XAML
<ComboBox x:Name="ComboBoxVersions"
SelectedIndex="0"
SelectionChanged="ComboBoxVersions_OnSelectionChanged"
ItemsSource="{Binding EnvironmentVersions}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

You could use something like this
<TextBlock Text="{Binding StringFormat=Version: {0}}" />

using ComboBox.ItemStringFormat:
<ComboBox ItemsSource="{Binding EnvironmentVersions}"
ItemStringFormat="version: {0}" />
or using ComboBox.ItemTemplate
<DataTemplate>
<TextBlock Text="{Binding StringFormat=Version: {0}}" />
</DataTemplate>
or
<DataTemplate>
<TextBlock>
<Run Text="Version " />
<Run Text="{Binding }"/>
</TextBlock>
</DataTemplate>

Here's a simple way:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Version " />
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
Since the ItemTemplate only defines how the items are displayed, the SelectedItem property of the ComboBox still holds the original value from your collection of version numbers.

You can add a string format to the binding in the datatemplate.
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringFormat=Version {0}}" />
</DataTemplate>
</ComboBox.ItemTemplate>

Related

WPF binding Listbox layoutpanel

I´m using devexpress and I want to do a binding with a Listbox, but I have an error. Here my code:
<ListBox x:Name="_list" >
<ListBox.ItemTemplate>
<DataTemplate>
<dxd:LayoutPanel
Caption="{Binding nameList}"
AllowHide ="False" AllowFloat="False"
GotFocus="panel_GotFocus" >
<TextBox Text="Hello" />
</dxd:LayoutPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
With this code, Caption {Binding nameList} is empty.
I have tried this.
<ListBox x:Name="_list" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox Text="{Binding nameList}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In this case, text in TextBox is correct, I need to use the first code.
You seem to be a bit confused about how to use this ListBox. First, you need a collection property to bind to the ListBox.ItemsSource property. Let's say you have a collection of User objects called Users:
<ListBox ItemSource="{Binding Users}" />
Now we want to define how each User should be displayed... all the properties of the User class will be available to the Binding inside the DataTemplate. Let's say that the User class has two properties; Name and Age:
<DataTemplate DataType="{x:Type YourDataTypeNamespace:User}">
<StackPanel>
<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding Age}" />
</StackPanel>
</DataTemplate>
Then putting it all together:
<ListBox ItemSource="{Binding Users}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type YourDataTypeNamespace:User}">
<StackPanel>
<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding Age}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

How to use converters without binding paths?

I have a Combobox whose ItemsSource is an ObservableCollection of int values.
My combobox itemtemplate consists on an image and a textblock which content is given by 2 converters.
How can I set this 2 bindings? The following code does not compile:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding, Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding, Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
You need to remove the , so:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>

How to trigger DataGridevents DataGridBeginningEdit, DataGridCellEditEnding with a Combobox in Silverlight? / CellTemplate for a Combobox

I want to use the DataGridevents (DataGridBeginningEdit, DataGridCellEditEnding, ..etc) to handle and detect changes. As far as I understood, without a "CellTemplate" these are not triggered. So I am trying to create an appropriate celltemplate using a TextBlock, but I guess it is not very straightforward with the binding I am using for the Combobox in the CellEditingTemplate, because I am using "DisplayMemberPath"..
There are examples of simpler cases but I couldn't find smth for this scenario. See Xaml snippet below;
<data:DataGridTemplateColumn Width="100">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" />
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
<data:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding DurationTypeList, Source={StaticResource itemSourceProvider}}"
SelectedValuePath="Code"
SelectedValue="{Binding Path=DurationTypeCode, Mode=TwoWay}"
DisplayMemberPath="Template" />
</DataTemplate>
</data:DataGridTemplateColumn.CellEditingTemplate>
</data:DataGridTemplateColumn>
Thank you
It turns out, i have two options..
Solution #1
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Left" Text="{Binding Path=DurationType.Template, Mode=OneWay}" />
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
<data:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding DurationTypeList, Source={StaticResource itemSourceProvider}}"
SelectedValuePath="Code"
SelectedValue="{Binding Path=DurationType, Mode=TwoWay}"
DisplayMemberPath="Template" />
</DataTemplate>
</data:DataGridTemplateColumn.CellEditingTemplate>
I changed the binding path from string to the object with Code and Template properties..
This blog helped a lot..

Data Binding with WPF

I'm new to WPF and this following has stumped me for a while now:
I have an observableCollection of People object in my model that is bound to my tabControl. So each my a new People object is added, a new tab is created with People.Title as the Tab's header.
Each People object has an ObservableCollection of Friend object. Inside of the Tab I would like to have a List of two textboxes, one for Friend.FirstName and another for Friend.LastName.
My first requirement is working fine, but the second one is giving me an error 'ItemsSource is already in use'
Here's my code so far:
<TabControl Name="ConversationTabs" Grid.Row="0"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource HeaderInfoTabControl}"
ContentTemplate="{StaticResource DialogueList}" />
<Window.Resources>
<DataTemplate x:Key="HeaderInfoTabControl">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
<DataTemplate x:Key="DialogueList">
<ItemsControl ItemsSource="{Binding Path=DialogueCollectionVM}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Sent}" />
<TextBlock Text="{Binding Path=DateSent}" />
<TextBlock Text="{Binding Path=Message}" />
</StackPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
I appreciate your help.
You cannot add items to an ItemsControl and use the automatic population (via ItemsSource) at the same time. If that StackPanel is supposed to be used for the items in the ItemsSource you should do this:
<ItemsControl ItemsSource="{Binding Path=DialogueCollectionVM}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Sent}" />
<TextBlock Text="{Binding Path=DateSent}" />
<TextBlock Text="{Binding Path=Message}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Syntax to bind to the current dataitem's default indexer in WPF?

I have a Listbox with an itemssource set to an ObservableCollection of DataRow. Let's say each DataRow has 5 columns for this example.
In the DataTemplate of the ListBox I have 5 textblocks (1 for each column). My question is how can I bind to an indexer of the row to get the columns value?
Here is my attempt but nothing displays so I must have the syntax wrong:
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=.[0]}" />
<TextBlock Text="{Binding Path=.[1]}" />
<TextBlock Text="{Binding Path=.[2]}" />
<TextBlock Text="{Binding Path=.[3]}" />
<TextBlock Text="{Binding Path=.[4]}" />
</StackPanel>
</DataTemplate>
I know that indexers can be used in bindings because I've done something like this already:
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Collection[0].Name}" />
<TextBlock Text="{Binding Path=Collection[1].Name}" />
<TextBlock Text="{Binding Path=Collection[2].Name}" />
<TextBlock Text="{Binding Path=Collection[3].Name}" />
<TextBlock Text="{Binding Path=Collection[4].Name}" />
</StackPanel>
</DataTemplate>
Any help on correcting my syntax would be appreciated.
Your syntax should do. However, the following must go also:
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=[0]} />
<TextBlock Text="{Binding Path=[1]} />
<TextBlock Text="{Binding Path=[2]} />
<TextBlock Text="{Binding Path=[3]} />
<TextBlock Text="{Binding Path=[4]} />
</StackPanel>
</DataTemplate>
Check your ItemsSource. Does it really provide an indexer that is of type int? Maybe you have an indexer of another type or even no index. Maybe it's another object than you expect it to be?

Resources