I have two properties, Related_Id and PageNumber. I want to bind these two values to a single label.
XAML code
<StackPanel>
<sdk:Label x:Name="RelatedItemIdLabel"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="{Binding CreateMessage.RelatedId}" />
</StackPanel>
current output: Related_Id
Desired output: Related_Id/ PageNumber
Could anyone help me to find a solution..
Thanks..
Try this:
<Label x:Name="RelatedItemIdLabel"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<Label.Content>
<MultiBinding StringFormat=" {0}/{1}">
<Binding Path="" /> //insert field 1
<Binding Path="" /> //insert field 2
</MultiBinding>
</Label.Content>
</Label>
This is the code you're looking for :
<StackPanel>
<sdk:Label x:Name="RelatedItemIdLabel"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<sdk:Label.Content>
<MultiBinding StringFormat=" {0}, {1}">
<Binding Path="{Binding CreateMessage.RelatedId}"/>
<Binding Path="{Binding CreateMessage.PageNumber}"/>
</MultiBinding>
</sdk:Label.Content>
</sdk:Label>
</StackPanel>
Related
I am writing the below code for implementing a Multibinding in WPF textblock
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-{1}">
<Binding Source="{Binding Path=localResource.bookdata_labelPageNO,Source={StaticResource LanguageManagerDynamic}}"/>
<Binding Path="PageNo"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
I am trying to load a string like "Page xx" where xx is the page number which is a property of the binded model and the string "Page" is loaded from the resource
But i am getting runtime error on this line # XAML . What is causing the error ?
This was my previous working code
<TextBlock Text="{Binding PageNo,StringFormat=page. {0}}" />
Can You try Like this
<TextBlock>
<Run Text="Page" />
<Run Text="{Binding PageNo}" />
</TextBlock>
Ok for pure xaml solution you can do this, assuming your resources are loaded properly.
<Window.Resources>
<sys:String x:Key="Page">Page</sys:String>
</Window.Resources>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Source="{StaticResource Page}"/>
<Binding Path="PageNo" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
I want to add data from 2 columns from a datagrid and display them using a single tooltip. I am able to achieve the result from 1 column only but when I try to concatenate the values doesn't show up.
<TextBlock Text="{Binding Message, Mode=OneWay}" Margin="4 0"
VerticalAlignment="Center" HorizontalAlignment="Stretch" >
<ToolTip>
<MultiBinding StringFormat="{}{0} - {1}">
<Binding RelativeSource="{RelativeSource Self}" Path="SourceName"/>
<Binding RelativeSource="{RelativeSource Self}" Path="Message"/>
</MultiBinding>
</ToolTip>
</TextBlock>
SourceName and Message are the values extracted from properties.
How do I show both of them in a single Tooltip ?
ToolTip should be a part of the TextBlock element
<TextBlock Text="{Binding Message, Mode=OneWay}" Margin="4 0"
VerticalAlignment="Center" HorizontalAlignment="Stretch" >
<TextBlock.ToolTip>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} - {1}">
<Binding Path="SourceName"/>
<Binding Path="Message" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</TextBlock.ToolTip>
</TextBlock>
Probably, the bindings should be also changed if you want to get information from the DataContext and not from the visual element.
I have a formatted string in a .resx file like so:
Blah: {0}
How do I use it in WPF binding to fill the {0} part?
i didn't tested it but...
https://social.msdn.microsoft.com/Forums/vstudio/en-US/f77ab886-2def-4cef-aed3-9ced24eb5776/using-stringformat-in-a-textblock-in-wpf?forum=wpf
so i guess you should do something like this :
<TextBlock Text="{Binding Path=MyStringParameter, StringFormat={Binding MyStringFormatResource}"/>
In addition Binding/StringFormat you can also use MultiBinding element.
<StackPanel>
<TextBox Name="countText" Text="4" />
<TextBox Name="totalText" Text="10" />
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Select {0} of {1}">
<Binding ElementName="countText" Path="Text" />
<Binding ElementName="totalText" Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
In a real sample you would bind something else but XAML elements but this shows you the idea.
I got WPF validation running (added ValidationRules to the binding) and with the template I can create nice adorners. There are many posting out there.
But I cannot find a way to display the error message outside of the adorned control in a fixed place like a TextBlock in a corner of the window e.g.
How could I achieve this? Can I bind all of my validation error messages to my DataContext (ViewModel here)?
Update: Thanks to an answer I got it partly working. The validation messages are now displayed in another label. As all the textboxes with their validation rules are created on the fly by code, the binding to do so is done this way:
Binding bindSite = new Binding();
bindSite.Source = this.validationErrorDisplayLabel;
BindingOperations.SetBinding(textBox, Validation.ValidationAdornerSiteProperty, bindSite);
But the validation messages are only forwarded to the adornersite for the last textbox for which this code was executed.
I reproduced the problem in this small example.
XAML:
<Grid>
<TextBox
Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}"
HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
<TextBox.Text>
<Binding>
<Binding.Path>Box1</Binding.Path>
<Binding.ValidationRules>
<local:RuleA />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox
Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}"
HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
<TextBox.Text>
<Binding>
<Binding.Path>Box2</Binding.Path>
<Binding.ValidationRules>
<local:RuleA />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock
x:Name="ErrorDisplay"
Background="AntiqueWhite"
Foreground="Red"
Text="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)[0].ErrorContent}"
HorizontalAlignment="Left" Margin="230,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" RenderTransformOrigin="2.218,-4.577" Width="177" Height="51"/>
</Grid>
The class RuleA produces a validation error when the value equals the string "A". The errors in the 2nd textbox are displayed in the TextBlock, the errors of the first one not (instead it uses the default template and gets a red border).
How can it work for both? The textblock does not need to sum up all errors but display the very first error.
You can use a BindingGroup in combination with the Validation.ValidationAdornerSite and Validation.ValidationAdornerSiteFor properties.
This blog post shows you an example of how to do this.
<StackPanel x:Name="FormRoot"
Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}">
<FrameworkElement.BindingGroup>
<BindingGroup Name="FormBindingGroup" />
</FrameworkElement.BindingGroup>
<TextBox>
<TextBox.Text>
<Binding BindingGroupName="FormBindingGroup"
UpdateSourceTrigger="LostFocus"
Path="Box1">
<Binding.ValidationRules>
<l:RuleA />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox>
<TextBox.Text>
<Binding BindingGroupName="FormBindingGroup"
UpdateSourceTrigger="LostFocus"
Path="Box2">
<Binding.ValidationRules>
<l:RuleA />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ItemsControl x:Name="ErrorDisplay"
Background="AntiqueWhite"
Foreground="Red"
ItemsSource="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)}"
DisplayMemberPath="ErrorContent" />
</StackPanel>
To commit the values as the user types, change the UpdateSourceTrigger values to PropertyChanged. Note that it isn't strictly necessary to use ValidationAdornerSite here; you could simply point the ErrorDisplay binding directly to the owner of the BindingGroup:
ItemsSource="{Binding ElementName=FormRoot, Path=(Validation.Errors)}"
Thanks to http://www.scottlogic.com/blog/2008/11/28/using-bindinggroups-for-greater-control-over-input-validation.html I was able to solve this with a BindingGroup and without ValidationAdornerSite.
<Window x:Class="BindingAndValidation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BindingAndValidation"
Title="Binding and Validation" Height="110" Width="425"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Grid x:Name="RootElement">
<Grid.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Grid.BindingGroup>
<BindingGroup Name="LocalBindingGroup">
<BindingGroup.ValidationRules>
<local:RuleGroup />
</BindingGroup.ValidationRules>
</BindingGroup>
</Grid.BindingGroup>
<TextBox
HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" LostFocus="TextBox_LostFocus">
<TextBox.Text>
<Binding>
<Binding.Path>Box1</Binding.Path>
<Binding.BindingGroupName>LocalBindingGroup</Binding.BindingGroupName>
<Binding.ValidationRules>
<local:RuleA />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox
HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
<TextBox.Text>
<Binding>
<Binding.Path>Box2</Binding.Path>
<Binding.BindingGroupName>LocalBindingGroup</Binding.BindingGroupName>
<Binding.ValidationRules>
<local:RuleA />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ItemsControl ItemsSource="{Binding Path=(Validation.Errors), ElementName=RootElement}" MinWidth="100" MinHeight="16" Margin="230,10,0,0" Background="AntiqueWhite" Foreground="Red">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Foreground="Red" Content="{Binding Path=ErrorContent}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="Button" HorizontalAlignment="Left" Margin="150,0,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" />
</Grid>
</Window>
The validation only occurs when you call CommitEdit. If you want to have it immediatly like I wished here you can use LostFocus
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
this.RootElement.BindingGroup.CommitEdit();
}
Of course for a greater project an attached property might help.
I have a ListView which gives me correct information. I want to apped at the end of each row, two TextBoxes in which user can edit, can anyone guide me?
This is the result I want to see John Smith textbox textbox.
Here is my code below:
<ListView.ItemTemplate>
<DataTemplate>
<Label x:Name="lblPerson">
<Label.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="FName" />
<Binding Path="LName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Label.Content>
</Label>
</DataTemplate>
</ListView.ItemTemplate>
I don't know if I understand correctly what your problem is, but inside the DataTemplate you can use a StackPanel or a DockPanel and place the Label and anything else you can, something like this:
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label x:Name="lblPerson">
<Label.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="FName" />
<Binding Path="LName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Label.Content>
</Label>
<TextBox Text="Something">
<TextBox Text="{Binding SomeField}">
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
Is this what you are asking? Regards