I have a WPF application. I have some labels and some datagrids which are bound to some public properties. Some of these properties are numerical values.
In the datagrids I have been using the line below to ensure the values only display two decimal places, which works. However when I use the same line below for my label it appears to have no effect on the display as the number shows to about 9 decimal places. I don't understand why it works for the datagrid but not the label?
StringFormat={}{0:0.##}
<Label Grid.Row="3" Grid.Column="1"
Content="{Binding Obs.Tstat, StringFormat={}{0:0.#}}"
HorizontalAlignment="Center" Foreground="{StaticResource brushLinFont}"
FontSize="13" FontWeight="Bold"/>
Updated code
<Label Grid.Row="3" Grid.Column="1"
Content="{Binding Obs.Tstat}" ContentStringFormat="{}{0:0.#}}"
HorizontalAlignment="Center" Foreground="{StaticResource brushLinFont}"
FontSize="13" FontWeight="Bold"/>
For label you need to use ContentStringFormat:
<Label Content="{Binding Obs.Tstat}" ContentStringFormat="{}{0:0.##}"/>
Reason:
Label's Content property is of type object and StringFormat is used only when binding property is of type String.
If you try your code with TextBlock's Text property it will work fine with StringFormat because Text property is of type string.
Just a quick addition I'd like to post along these lines in case anyone else runs in to it... My application uses localization since it has multi-country support, but we also support user's system settings. We noticed ContentStringFormat defaults to your UI culture.
That caused an issue in one of our forms where the user's machine-specific decimal places they had configured in windows settings were not respected when you specified the ContentStringFormat.
Since the ContentPresenter simply takes the string format without the converter culture you could normally specify in the binding , this means that a format of say: 0:N will only return two decimal places if English is my current UI culture, even though I have 5 decimals specified on my windows settings.
In our case we applied some binding overrides to work around this, but mainly just wanted to add this extra bit of info in case anyone else runs in to it ;)
Related
So here's the situation:
I have a label (custom control derviative of it, if it matters), and I need to get its width and height with MVVM. However, if I set either of the parameters to {Binding XXX}, they are no long Auto and thus when I change the font in runtime their size doesn't update.
I read about using ActualWidth/Height, which sounds like just what I need besides the fact that it's not a dependence parameter, thus it seemss like I'd need to break MVVM for it.
Are there any better solutions?
EDIT
Well, the element in XAML looks nothing special. Just a million of bindings.
<local:DraggableLabel
Content="123"
Margin="{Binding Label2Position, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontFamily="{Binding Label2Font.Family}"
FontSize="{Binding Label2Font.Size}"
FontWeight="{Binding Label2Font.Weight}"
FontStyle="{Binding Label2Font.Style}"
Foreground="{Binding Path=Label2Color,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource ColorToBrushConverter}
}"/>
The default is,
Width="Auto"
which doesn't have to be written explicits, but can (changes nothing). It makes it resize when the font changes. If I set it to
Width="Binding {Label1Width}"
The binding works fine, but I no longer get the auto-adjustment.
Okay, so I found a workaround.
Since I had create a custom control, I was able to create a new DependencyProperty called RealWidth, then I added a OnSizeChanged event that updates it with the value of ActualWidth that you CAN get from inside the element every time the size of the element changes.
Okay so I know I can fix this with some string formatting on the textbox, but it's bugging me why this is happening in the first place. I have a slider control, which is going to get its max, min, and precision values from the viewmodel, depending on which page it's loaded into.
As an example, I've hard coded these values.
<DockPanel VerticalAlignment="Center"
Margin="40,0,0,0"
Height="100">
<TextBox Text="{Binding ElementName=Slider, Path=Value, UpdateSourceTrigger=PropertyChanged}"
DockPanel.Dock="Top"
TextAlignment="Right"
Width="634"
Margin="0,0,0,20" />
<Slider DockPanel.Dock="Bottom"
Name="Slider"
Width="634"
Padding="0"
Maximum="5000"
Minimum="-5000"
SmallChange="0.01"
LargeChange="0.01"
TickFrequency="0.01"
SnapsToDevicePixels="True"
IsSnapToTickEnabled="True" />
</DockPanel>
I know I probably don't need a few of those properties, but threw them in trying to fix this.
For the most part this has worked, and the slider is being constrained to two decimal places. But I've noticed (especially with large ranged) that I'm still getting random values which are ignoring this. For example when I set a range of -5000 to 5000 I still randomly get values like 80.20000002.
I know I can apply a string format to the textbox to resolve the issue, (although a tad annoying with the viewmodel setting the precision) just wondering why it's happening.
As an aside, users also need to be able to set the value using a keyboard, again this works perfectly, but I'm wondering if there's a way to make the slider textbox acceppt a decimal point without having a number behind it.
I've got a really weird problem related to .NET 4.5.
Today a User told me that he isn't able to enter floating numbers into a Textbox (like "2.75").
The textbox just doesn't accept ".", which is the correct 'seperator' for floating numbers in my Culture ("de-CH").
This issue occurred after I compiled the software with .NET 4.5 (formerly it was 4.0).
I can reproduce this error. All other textboxes in the application are working fine.
The textbox is a regular WPF Control. No fancy user defined control or anything like that.
Again: the textbox just doesn't accept '.' as a character. It seems that it completely ignores it. Every other character (even special ones like "#") are fine.
Recompiling the application on .NET 4.0 solves the problem.
The xaml for the textbox is:
<TextBox x:Name="_Hours" Grid.Row="9" Grid.Column="1" VerticalAlignment="Center"
TextAlignment="Center" FontWeight="Bold" FontSize="16" Text="{Binding ProcessHours,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="Hours_TextChanged" />
Definition of ProcessHours:
partial class ProjectTask
{
...
public double TotalProcessHours { get { return ProjectBookings.Sum(b =>
b.ProcessHours); }}
...
}
Hours_TextChanged is:
private void Hours_TextChanged(object sender, TextChangedEventArgs e)
{
UpdateHoursValidity();
}
UpdateHoursValidity() just fades a Text Message below the actual textbox. It is not connected with the "broken" textbox in any way:
private void UpdateHoursValidity()
{
string key = IsInvalidHoursWarning ? "ShowWarningStoryboard" :
"HideWarningStoryboard";
var storyboard = FindResource(key) as Storyboard;
if(storyboard != null) storyboard.Begin();
}
So nothing fancy here either.
What I tried so far:
- removing the textbox, recompiling, adding the textbox again, recompiling -> same situation
Setting the Language property of the textbox specifically in xaml (Language=de-CH)
Setting the culture according to these tips:
how to set default culture info for entire c# application
Setting the culture according to this blogpost:
http://www.west-wind.com/weblog/posts/2009/Jun/14/WPF-Bindings-and-CurrentCulture-Formatting
There is NO Message on the debugconsole when I try to enter a ".".
Any ideas on this one?
Thanks in advance!
This is a fairly well known (and documented) issue relating to TextBox controls and data bound float values. You can fix this issue, by adding a StringFormat to your Binding:
<TextBox x:Name="_Hours" Grid.Row="9" Grid.Column="1" VerticalAlignment="Center"
TextAlignment="Center" FontWeight="Bold" FontSize="16" Text="{Binding ProcessHours,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat={}{##.##}}"
TextChanged="Hours_TextChanged" />
Please adjust the format to suit your situation. You can find more formats in the Custom Numeric Format Strings post at MSDN.
There is a detailed discussion on the .NET 4.5 change that causes this issue on the Microsoft Connect site: https://connect.microsoft.com/VisualStudio/feedback/details/737301/binding-to-wpf-textbox-seems-to-be-broken-in-net-4-5-beta
In addition to the StringFormat workaround, another option is to set a Delay for the binding.
I'm creating a menu from a ListBox. I'm using FontAwesome to create some font-icons. This is part of the ListBox ItemTemplate.
<TextBlock FontFamily="FontAwesome" VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="32" Text="{Binding MenuCode}"
ToolTip="{Binding Tooltip}" >
The problem resides within the TextBlock's Text. I need to display the symbol, not the menu code. So, for example, if I use Text="" directly, then the music icon appears (fixed for all the items), but when I use DataBinding (each item has a different symbol): Text="{Binding MenuCode}" then the text (that is, the menu code as string) appears (as text, no icon). I guess problem is related with encoding, but can't fix it. Any idea?
Wrong escape sequence. HTML uses '#&x' while C# uses \u. So your "#&xF001" would become "\uF001"
Currently my DateTimePickers are blank, I would like them to have a default setting i.e
Today.AddYears(20); & Today.AddDays(5);
What I have done at the moment is 'DateTimePicker.Text = DateTime.Today.AddYears(-100).ToString();' As you can probably tell, this isn't working hence why I'm asking the question.
Bit of information :- I need it so that if they arent changed and the button is pressed it uses the default dates. If they are changed, I obviously need to use the changed dates.
Suggestions.
XAML ADDED:
<igEditors:XamDateTimeEditor Name="startDateTimePicker"
Grid.Row="1"
Grid.Column="1"
xmlns:igEditors="http://infragistics.com/Editors"
Height="18"
Width="100"
Format="yyyy-MM-dd"
VerticalAlignment="Top"
HorizontalAlignment="Center" />
Setting the Value property should do the trick:
DateTimePicker.Value = DateTime.Today.AddYears(-100);
And since it's type is DateTime, you don't need any ToString conversions.
Just set the value property of DateTimePicker Control.