In my current project i'm trying to show a label which has a TimeSpan binding.
Actually the xaml looks simple:
<Label Content="{Binding ElementName=Root, Path=DataSource.TimeTotal, StringFormat={}{0:hh\:mm}}"/>
Which is exactly what is shown in this question. But it doesn't work, it shows always the full time and not only hours + minutes.
I tested a lot of solutions but none of them worked.
Suggested solution
Maybe just try to use TextBox instead of a Label and bind Text instead of Content. You can find example of the binding here: How to format TimeSpan in XAML. It's also worth noticing that TextBlock is more lightweight then Label, so it should be used when possible.
Alternative solutions
If you want to use Label for some reason, there seems to be a property called ContentStringFormat of a Label itself, so your xaml can look like:
<Label Content="{Binding ElementName=Root, Path=DataSource.TimeTotal}" ContentStringFormat="hh\\:mm"/>
Another solution would be implementing a custom IValueConverter, where you can pass string format as converter's parameter and format the value manually in the converter's code. This solution should then work correctly for all appropriate control types. More about value converters can be found here and here.
String formatting properties
As Erode wrote in the comment, there seem to be other controls for which StringFormat does not work.
However, for controls derived from ContentControl you should be able to use ContentStringFormat and for controls derived from ItemsControl, there is a ItemStringFormat property. There is a link with few samples presenting how to use those:
http://blogs.msdn.com/b/llobo/archive/2008/05/19/wpf-3-5-sp1-feature-stringformat.aspx
It works with TextBlock, which is the lightweight equivalent to Label. Whenever you're binding to a dependency property in a control that uses a ContentPresenter to display the data, it seems to eat the StringFormat you've provided. (in Label, Button, etc). Wish someone would let us know why! You can nest a TextBlock within the Label or just go with a TextBlock (which, unless you need access text, is usually a better choice anyway).
Related
I have a WPF TextBox that has it's text value bound in XAML. This works fine and, as expected, when the associated value is loaded to the field, it is formatted as desired.
My issue is when the user enters the text field to modify the value, I want to strip away the formatting, and display the raw underlying value.
To do this, I tried to set the BindingExpression.ParentBinding.StringFormat property, on the text boxes binding from within a GotFocus event. However, when I tried to set the StringFormat property to an empty string, I got the following exception:
Binding cannot be changed after it has been used.
So, after a control has been bound to a data model object, is there a straight-forward way that I can modify the string format of the TextBox? I'm willing to change how I format the value of the control, but the end desire is to strip the formatting of the data when it is being edited, and re-instating the string formatting once the user exits the field.
I would probably try it differently. It sounds like you are using the same TextBox for the formatted value and editing the raw value. It would be cleaner to use two different TextBoxes for View and Edit, or package it in a UserControl. Also, I would use two properties, e.g. RawText and FormattedText, and the UserControl would have DependencyProperties with bindings to both properties. The UserControl would automatically switch to the Edit TextBox. The question of "how does the automatic switching" work may be a challenge though. You probably need to use the GotFocus of the View TextBox as you mentioned, although it might not be a bad idea to have an actual Edit button that switches it for you.
I understand about switching to WPF. There is quite a bit of adjustment (aka learning) when switching to WPF. I would think of it as designing a form or control that is "fit for purpose". You don't have to create a new UserControl though. You could do something similar to StackOverflow where there is an Edit TextBox and then the View area, that would be equivalent to the Raw and Formatted values. You would control the Visibility of the Edit TextBox through a BoolToVisibilityConverter when you are in edit mode. Create a public bool IsEditing property on your ViewModel and bind that to the <EditTextBox Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}}" Text="{Binding RawText}" ...etc... /> After working with WPF for a while, you really appreciate data binding and it makes it hard to go back to plain WinForms (at least for me - not to say there aren't challenges though!).
I feel like I'm going to reinvent wheel so I would like to know if WPF has bult-in support for what I'm trying to achieve. I'm building an app that will allow people to enter some text in a textbox, and then see it formatted in a textblock.
I would like that the user be able to format the text himself by inputing things such as
This [BusinessSpecificStyle] is [/BusinessSpecificStyle] a sample text
My purpose is to be able to easily change the presentation of all my documents by simply changing the underlaying rules in BusinessSpecificStyle. However I don't know what is the best way to implement that with WPF. I was thinking of using a BBCode parser like this one but supposing I go that way, I don't see how I will be able to convert the resulting XAML into TextBlock children programatically, and I seriously wonder if there isn't some kind of built in support for that.
Thanks for your help
IValueConverter is what you are looking for.
Create the converter and format your text based on the bindings passed from the XAML.
You can get multiple samples over the net for creating IValueConverter. Refer to the link here and here to get you started.
Not sure if you are asking for Converter here. To me it reads that you want to control the style of a block of text depending on some background and common style?
If that is the case, you want to set the inlines of your text block to seperate your text into run elements, which can reference a specific style resource.
<TextBlock>
<TextBlock.Inlines>
<Run>This</Run>
<Run Foreground="{StaticResource BusinessSpecificStyleForeground}">is</Run>
<Run>a sample text</Run>
...
in this case, you create a resource which defines the binding styles for run or bind the Style in it's entirety.
Apologies if I am making up a new question, I see you've marked an answer but wanted to add this just in case.
It's my first time using WPF, I'm still getting used to the controls. I have a couple of textboxes, each having a Binding to a string somewhere. Works great when running the program, but in the editor.. all I see is blank emptyness. When I mouse-over I can see the border of the textbox, but having to mouseover to find all my elements in my program.. well, that's not a nice way to design a layout.
Is there any way to have 'default' text visible in the editor? Some parameter I'm missing, some border I can activate only during editing mode, heck, -any- way I can see what I'm doing without influencing what the program looks like when being ran?
//Properly binds and displays text, but invisible in the editor.
<TextBlock Height="48" Margin="26, 191, 0, 0" Text="{Binding FirstTextBox} Width="175">
ANSWER::
After hearing the keyword 'Design-Time', How to set a value to display for bound properties in WPF design mode? brought me to the proper answer.
you can set DataContext to your Model. If you want to see your property value in editor.
Best Regards
Did you try by using FallbackValue?
Here is an example from other post to set a default text visible as you asked.
WPF Binding - Default value for empty string
I would like to, based on state, display one or the other control assigned to a grid's cell, such as:
<Button x:Name="btnBla" Grid.Row=42 Grid.Column=7></Button>
<TextBlock x:Name="txtblockOh" Grid.Row=42 Grid.Column=7 IsEnabled="false"></TextBlock>
...and then in the code-behind:
btnBla.IsEnabled = someBool;
txtblockOh.IsEnabled = ! btnBla.IsEnabled;
Is this the preferred method to accomplish this?
if you want to "Show" one at a time as your question states, you should change the Visibility property insted of the IsEnabled.
You CAN do it in code, although I always recommend against manipulating UI elements in code (be it WPF, Silverlight or WinRT), all XAML-based technologies are much friendlier if you use the MVVM way of thinking.
Yo can be look at this page: Visibility
I have a control that we could identify as similar to ListBox control. Each item is represented with one element (example TextBlock). What i would like is to change the layout of this item, so that it contains two TextBlocks. So I create a ControlTemplate, put a Border Grid, TwoTextBlocks, and all is well. Now the problem:
I need to be able to localize the text in the item, and I did this normally like this:
<... Text="{Binding Strings.SomeString, Source={StaticResource ApplicationResources}}" />
Now I need to be able to do the same with both TextBlocks. So i thought I need to create a custom type that this item will bind to, and expose two propertiws: Title and Description. If I expose this properties as string type, everything works ok, but I am loosing markup binding that I used previously. How to achieve the same with two properties? The result should be like:
<... Title="{Binding Strings.SomeString, Source={StaticResource ApplicationResources}}", Description="{Binding Strings.AnotherString, Source={StaticResource ApplicationResources}}" />
I was able to make Localization work with ResourcemManager class, but it gets even complicated in order to provide localization to be applied dynamically at runtime.
So, what do I need to do to be able to use above code? Then I just need to implement INotifyPropertyChanged on ApplicationResource and all is set.
Great!
I'm going to do the same thing you did here. Yeah, I have a solution but I'm not sure if it works till now.
First, we need a LocalizationManager which holds a dictionary.
For example, if you need to localize a user account window, just do this
<TextBlock Text="something, UsernameKey">
And the localizationManager will map UsernameKey to "Username" or other language
Second, a xaml extension which find the value of the key from LocalizationManager.
I wonder if this custom extension could derived from Binding extension, if so, this'll be very easy, just create a Binding Object to the target. If not, I think holding a WEAK reference to the UIElement by xaml extension to dynamic update the text is proper.
This solution is simple but not generic. There're some language read from right to left. It asks the application to show content from right to left.
So, I have another generic solution but more complex.
Instead of xaml extension, we use an attach dependency property.
Do it like this:
<TextBlock LocalizationManager.LocalizationKey="UsernameKey" />
So, the problem now is how to set "Text" property by LocalizationManager?
We use adapters, LocalizationManager will search proper adapter for type "TextBlock"
So, when the application is booting, we register some adapters to LocalizationManager:
LocalizationManager.Current.RegisterAdapter<TextBlock>(new TextBlockAdapter())
This solution is more generic, it supports any kind of control if you provide adapter, but as you see, this solution needs more work and much more complex than the former one.
I hope these design solutions could help you~