Bind ObservableCollection count to wpf label and format the label - wpf

I have a label where I want to show the number of selected items in a list ( list items are selected from a grid ). That all works well and the label displays the number. What I want is to make the label display "5 items selected". Right now, I just get the number 5. Here is the xaml:
<Label Height="23" HorizontalAlignment="Left" Margin="7,2,0,0" Name="lblSelectionSummary" VerticalAlignment="Top" Width="557" FontFamily="Arial" >
<Label.Content>
<Binding Path="SelectedRows.Count" />
</Label.Content>
</Label>
I'm close on this guy.

you just need to specify the StringFormat in your binding
this should do
<Binding Path="SelectedRows.Count" StringFormat="{}{0} items selected"/>
above may not work for Label as it follows Content model , so you may need to use TextBlock instead
sample
<TextBlock Height="23" HorizontalAlignment="Left" Margin="7,2,0,0" Name="lblSelectionSummary" VerticalAlignment="Top" Width="557" FontFamily="Arial" >
<TextBlock.Text>
<Binding Path="SelectedRows.Count"
StringFormat="{}{0} items selected"/>
</TextBlock.Text>
</TextBlock>
or
<TextBlock Height="23"
HorizontalAlignment="Left"
Margin="7,2,0,0"
Name="lblSelectionSummary"
VerticalAlignment="Top"
Width="557"
FontFamily="Arial"
Text="{Binding SelectedRows.Count, StringFormat={}{0} items selected}" />
Use string format with a Label
StringFormat in binding works for string type properties, and since type of Content property of Label is object so StringFormat does not work
thanks to blindmeis for the hint
since a Label follows Content model it uses ContentStringFormat to format the value, below is an example to use the same
<Label Content="{Binding SelectedRows.Count}"
ContentStringFormat="{}{0} items selected" />

Related

WPF MVVM How read property value, binded to another element, in viewmodel

I'm trying to do a simple thing, I've searching around the web but I've not found a solution. I use ColorPicker from Wpf Toolkit library, the property SelectedColor is binded to an element Label on Foreground Property.
It works correctly, when I change color from color picker the label changes its color, but I can't find a way to get the selected color in my viewmodel.
Normally I used to bind my property to viewmodel and manage it on onPropertyChanged event, but how can I do in this situation?
XAML
<Label Name="LabelMeasureValue1" Content="{Binding TrendingMeasure1Value}" Style="{StaticResource LabelStyleBold}" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="2"/>
<wpfTool:ColorPicker Name="ColorPick1" DisplayColorAndName="True" ShowStandardColors="False" AvailableColors="{Binding ColorItems}" SelectedColor="{Binding ElementName=LabelMeasureValue1, Path=Foreground, Converter={StaticResource brushColorConv}}" Tag="{Binding Path=SelectedItem, ElementName=ComboBoxMeasure1}" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" Height="30">
<wpfTool:ColorPicker.IsEnabled>
<MultiBinding Converter="{StaticResource enblTrendConv}">
<Binding Path="Device.EsitoUltimaLettura" />
<Binding Path="IsGraphRunning" Converter="{StaticResource invBoolValueConv}"/>
</MultiBinding>
</wpfTool:ColorPicker.IsEnabled>
</wpfTool:ColorPicker>

Define ComboBox' DataTemplate for TextBox (and define search pattern) when IsEditable is True?

I have a ComboBox whose ItemsSource is binding to a collection and the SelectedItem is binding to the properties of my VieModel. Let's call the binding properties AvailableOptions and TargetOption in ViewModel. And type of collection item and TargetOption is called MyOption. I have such requirements but I don't know how to fulfill them all:
It should be OK for the binding TargetOption to have NULL as value
I want to set a DataTemplate for the target type in TargetOption collection to be displayed in the ComboBox
If possible, I want use different DataTemplate for MyOption when then are in the drop-down of ComboBox and when one item is selected. Because my UserControl has limited space so it should be compact when item is selected and during the selection it should provide more information
As I said, I don't know how to do all of them. At first I have the XAML like this:
<ComboBox SelectedItem="{Binding SelectedOption} ItemsSource="{Binding AvailableOptions}" >
<ComboBox.ItemTemplateSelector>
<MyNameSpace:ComboBoxItemTemplateSelector ItemTemplate="{StaticResource OptionDetailTemplate}" SelectedItemTemplate="{StaticResource OptionSimpleTemplate}" />
</ComboBox.ItemTemplateSelector>
</ComboBox>
With a customized ItemTemplateSelector. I am able to do the requirement 2) and 3). My OptionDetailTemplate looks like this:
<DataTemplate x:Key="OptionDetailTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
</StackPanel>
</DataTemplate>
and OptionSimpleTemplate looks like this:
<DataTemplate x:Key="OptionSimpleTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Number}" />
</StackPanel>
</DataTemplate>
But now the problem is requirement 1). When the user select one option from the drop down list of the ComboBox, he can't put it as NULL back which should be allowed. This is because AvailableOption doesn't have a NULL object
I see that if I set IsEditable to True for the ComboBox, and set TextSearch.TextPath to Code, it allows the text quick search/assign and also allows to have a NULL value when the search text is totally deleted. But now when I ever select one, it only displays Code (the OptionTemplate does not have any effect any more because now it displays the selected item in a TextBox). This is not good since only Code is not enough for the user to tell what Option it is. But since I have multiple properties in MyOption class, how can I define the DataTemplate for the TextBox and also define the search routine?
I have to be honest that I didn't fully understand your first requirement and its ramifications. however, I am really just answering to let you know that you don't even need to use a DataTemplateSelector to select between your two DataTemplates. If you do not set the x:Key value on them, then they will be applied to the relevant items implicitly:
<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:TargetOption}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
</StackPanel>
</DataTemplate>
...
<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:MyOption}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Number}" />
</StackPanel>
</DataTemplate>
Furthermore, you could do all this data binding with just a single TextBlock if you use a MultiDataTrigger:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}|{1}">
<Binding Path="ShortName" />
<Binding Path="Code" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Perhaps if you try clarifying your remaining problem (in your question), I might understand?

How to add a tooltip using IValueConverter

I am looking for a solution to add a tooltip for a button using value converter.
This is because some part/text of this tooltip is calculated dynamically.
For instance i have an application with some "launchable" tasks in it in such a way that clicking any/all of these tasks launches another application.
In this task list, there is a button "Launch Tasks" with count depending upon the no. of tasks selected to launch.I need to show a tooltip for this button only.Like:
"Launch Tasks(2)", this is for two tasks selected.
Can someone please help in writing a converter for the same and then how to bind the same in XAML?
Update:
Earlier it is something like as below, but problem is tooltip shown is not upto the standards and not clearly visible, so i thought of removing the same and used converter instead.
<ToolTipService.ToolTip>
<ToolTip>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="ttlblActivityCount" Text="{Binding LaunchTaskButtonTitle, Source={StaticResource ResourceData}}" />
<TextBlock x:Name="ttlblActivityCountStart"
Margin="2,0,0,0"
Text="("/>
<TextBlock x:Name="tttxtActivityCount" Text="{Binding Path=SelectedActivitiesCount}"/>
<TextBlock x:Name="ttlblActivityCountEnd"
FontWeight="Bold"
Text=")" />
</StackPanel>
</ToolTip>
</ToolTipService.ToolTip>
Using a StackPanel to artificially combine a string is yes pretty much something you don't want to do. However you don't have to use an IValueConverter for this
If you have a property for SelectedActivitiesCount and you want to bind it's tooltip with some static text and the property a simple example could be:
<Button Content="Launch Tasks">
<Button.ToolTip>
<TextBlock Text="{Binding SelectedActivitiesCount, StringFormat=Launch Tasks({0})}" />
</Button.ToolTip>
</Button>
^^ With this output would look like: "Launch Tasks(2)" where SelectedActivitiesCount -> 2
If the text("Launch Tasks") is also dynamic:
<Button Content="Launch Tasks">
<Button.ToolTip>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="LaunchTaskButtonTitle" Source="{StaticResource ResourceData}" />
<Binding Path="SelectedActivitiesCount" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Button.ToolTip>
</Button>
^^ With this output would look like: "Launch Tasks(2)" where SelectedActivitiesCount -> 2, LaunchTaskButtonTitle -> Launch Tasks
Choose whichever method is applicable for you.

Filter in WPF XPath Expression

I have a ComboBox which lists the contact methods shown below. The ComboBox displays the correct values therefore the ItemSource Binding is working.
What i am trying to archive is that to display the selected contact method on application startup. I tried to bind the selected value to the ComboBox.Text attribute but i can't figure out how to set the filter.
This is my input data:
<Contact ShowsInterest="true">
<Name>Tester</Name>
<Lastname>Test</Lastname>
<ContactMethods>
<ContactMethod Selected="False">Phone</ContactMethod>
<ContactMethod Selected="False">Email</ContactMethod>
<ContactMethod Selected="True">Letter</ContactMethod>
<ContactMethod Selected="False">Mobile</ContactMethod>
</ContactMethods>
</Contact>
This is my ComboBox:
<ComboBox Name="combobox1"
ItemsSource="{Binding XPath=Contact/ContactMethods//*}"
Width="100" Height="25">
<ComboBox.Text>
<Binding XPath="Contact/ContactMethods//*[#Selected='true']"/>
</ComboBox.Text>
</ComboBox>
The XPath Expression should do the following: Display the Element under Contact/ContactMethods/ where selected equals true.
EDIT:
Even setting the Text Property directly won't work.
<ComboBox Name="combobox1"
ItemsSource="{Binding XPath=Contact/ContactMethods//*}"
Width="100" Height="25">
<ComboBox.Text>
Phone
</ComboBox.Text>
</ComboBox>
I guess i have to use the SelectedValue Property:
<ComboBox Name="combobox1"
ItemsSource="{Binding XPath=Contact/ContactMethods//*}"
Width="100" Height="25">
<ComboBox.SelectedValue>
Phone
</ComboBox.SelectedValue>
</ComboBox>
EDIT2:
This is the working solution, thanks to MikroDel
<ComboBox Name="combobox1"
ItemsSource="{Binding XPath=Contact/ContactMethods//*}"
Width="100" Height="25">
<ComboBox.SelectedValue>
<Binding XPath="Contact/ContactMethods/ContactMethod[#Selected='True']"/>
</ComboBox.SelectedValue>
</ComboBox>
This is the correct one :
<Binding XPath="Contact/ContactMethods/ContactMethod[#Selected='True']"/>

Does StringFormat feature of WPF Xaml work on Label.Content?

I have bind my Amount Label's Content Property to a decimal property via DataContext. I am trying to apply stringformat but see no effect. Does StringFormat feature work on Label controls ?? Please tell me on which controls does this feature work. BTW following is the code for the Label Control for whom i want to apply the currency formatting
<Label Grid.Column="2" Content="{Binding Path=Amount, StringFormat={}{0:C}}" Height="23" HorizontalAlignment="Left" Margin="100,10,0,0" Name="tb" VerticalAlignment="Bottom" Width="120" />
StringFormat works on properties of type string (when the object you are binding to is being converted to a string the string format is applied). The Content property is of type Object.
You can place a TextBlock inside your label to achieve the desired effect:
<Label Grid.Column="2" Height="23" HorizontalAlignment="Left" Margin="100,10,0,0" Name="tb" VerticalAlignment="Bottom" Width="120">
<TextBlock Text="{Binding Path=Amount, StringFormat={}{0:C}}"/>
</Label>
Try ContentStringFormat
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/866f7934-8b10-4872-b306-122674fad5fa/
<Label Content=ā€{Binding Amount}ā€ ContentStringFormat=ā€Cā€ />

Resources