Validation is not working in Textbox - wpf

I have a TExtBox and have created a ValidationRule class from here and this is my xaml :
<TextBox Name="ctsTxt" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}"
local:SimpleValidator.ValidationType="{x:Type system:Double}"
Validation.ErrorTemplate="{StaticResource validationTemplate}"
Style="{StaticResource txtBoxStyle}"
Grid.Column="1" Grid.Row="2" Margin="2"
/>
As per this and the validator class, the textbox sh accept only double input, but it accepts everything.
What's wrong in xamls that my validation is not happening at all.
Any help is appreciated.

Did you try setting your Text Binding like this?
Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"

Related

Link textbox to combobox - not working

I have a WPF usercontrol with a combobox & textbox. I want the textbox to hold the value of the selected item in the combobox and it works fine if I use SelectedValue in the binding path. However if I try to use the Title column of the combobox (SelectedValue.Title) the value of the textbox is overwritten but nothing is displayed. Can anyone tell me what I am doing wrong? My code sample is below. I am a newbie at this so please be kind :)
<ComboBox x:Name="ComboProject" Grid.Column="4" Grid.Row="0" TabIndex="14"
ItemsSource="{Binding Source={StaticResource Projects}, XPath=./Project}"
SelectedValuePath="#Item"
Tag="Project Number"
TextSearch.TextPath="#Item">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text= "{Binding XPath= #Item}" Width="90" />
<TextBlock Text= "{Binding XPath= #Title}" Width="220" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox x:Name="loaded" Text="{Binding Path=SelectedValue.Title, NotifyOnSourceUpdated=True, ElementName=ComboProject}" Grid.Row="2" Grid.Column="4" Tag="Project Title" TabIndex="15"/>
You set SelectedValuePath="#Item", so that's what SelectedValue has right now. Try setting it to Title and binding directly to SelectedValue:
<ComboBox x:Name="ComboProject"
ItemsSource="{Binding Source={StaticResource Projects}, XPath=./Project}"
SelectedValuePath="#Title">
<ComboBox.ItemTemplate>
...
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Text="{Binding SelectedValue, ElementName=ComboProject}" />
I removed some other code for clarity of example.
EDIT :
Ok, if you want to use SelectedValue for other purposes we can bind TextBox to SelectedItem instead. If the Title is an attribute of a selected XML node, then we can access it like this:
<TextBox Text="{Binding SelectedItem.Attributes[Title].Value, Mode=OneWay, ElementName=ComboProject}" />

Binding a ComboBox selection to the background color of a border.

Please forgive my ignorance. I am new to vb.net and WPF. I have a comboBox that has a list of colors like this. By the way this is in WPF.
Public Sub New()
InitializeComponent()
cmbColors.ItemsSource = GetType(Colors).GetProperties()
End Sub
In the XAML the comboBox is created as follows:
<ComboBox Name="cmbColors" HorizontalAlignment="Left" Margin="29,35,0,0"
Grid.Row="1" VerticalAlignment="Top" Width="120">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16"
Margin="0,2,5,2"/>
<TextBlock x:Name="cmbColorsText" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
What I'm trying to do is when the program is run start with a beginning background color of grey, and when a new background color is selected from the comboBox the back ground will update.
Here's the XAML of the element that I'm trying to bind to the selection.
<Border BorderBrush="{x:Null}" Grid.Column="1" Grid.Row="1" Background="{Binding Text, ElementName=cmbColors}">
<TextBlock Text="PRACTICE" Style="{StaticResource linkButtons}"/>
I have gone through every (string) type in the property window for the border>background>create binding>Element>comboBox and for some reason (that I can't determine) I have either missed the appropriate one or am looking at this the wrong way.
Thank you in advance!!!
You are binding the Background to a string, but the Background will need a ColorBrush. So, if your combo ItemsSource already contains items that are of ColorBrush then you can just bind to SelectedItem rather than Text.
Or you can use a converter in your Background binding, that takes the string and returns a SolidColorBrush, say.
Change the binding to
<Border BorderBrush="{x:Null}" Grid.Column="1" Grid.Row="1" Background="{Binding SelectedItem.Name, ElementName=cmbColors}">
<TextBlock Text="PRACTICE" Style="{StaticResource linkButtons}"/>
The Text property of the ComboBox is returning the result of the ToString() method of the PropertyInfo object, so for instance if you select Black, it will be "System.Windows.Media.Color Black" and won't be parsed as a valid color.

Multiselect ComboBox, Force it to always display the same text

I have a multiselect combobox that works fine. Except for the text. I want it to always have the same text ("Commodity Filter") regardless of what the user has selected.
If I set iseditable to true and the text to CommodityFilter it looks fine until the user makes a selection, then it is garbage (displays object type name). How can I hard code some text there? (Actually ideally i would databind it so it can change depending on whether anything is selected, but that would be a bonus at this point)
<ComboBox IsEditable="True" Text ="Commodity Filter" ItemsSource="{Binding Path=ActiveCommodities}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Width="20" />
<TextBlock Text="{Binding Commodity}"
Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I ended up creating a custom object for populating the ComboBox (which had the IsSelected property and implemented INotifyPropertyChanged) because I was creating several comboboxes to control filtering. Once I did this is was trivial to override the tostring on the customobject and pass in the appropriate text. So the xaml did not change much.
I would have preferred to overlay with a text box but that seemed to be beyond my abilities to get a polished look in a reasonable time.
<ComboBox ItemsSource="{Binding Path=ActiveFuturesMonths}"
IsEditable="True"
IsReadOnly="True"
Text="Futures Month Filter" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Width="20" />
<TextBlock Text="{Binding Text}"
Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Actually the crux is in setting -
IsEditable="True"
IsReadOnly="True"
Text="Futures Month Filter"
rather than creating custom object. thanks a lot it helped.

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ā€ />

Dataform fields won't appear

I am trying to learn how to use the Silverlight 3 DataForm control, because I need to define the DataForm fields myself in the XAML code, that is, I don't want to use the AutoGenerateFields property.
My problem is: the dataform works perfectly when the AutoGenerateFields is set to true, but when I create a DataForm and set the fields manually and run the application, all I get is an empty blank rectangle where my form and its fields should be.
I created a blank Silverligh Navigation Application to test this, and below is the code of the Home.xaml page:
<Grid x:Name="LayoutRoot">
<StackPanel>
<!-- This doesn't work. It renders a blank rectangle -->
<dataFormToolkit:DataForm x:Name="DataForm">
<dataFormToolkit:DataForm.EditTemplate>
<DataTemplate>
<StackPanel dataFormToolkit:DataField.IsFieldGroup="True">
<dataFormToolkit:DataField>
<TextBox Text="Test1" />
</dataFormToolkit:DataField>
<dataFormToolkit:DataField>
<TextBox Text="Test2" />
</dataFormToolkit:DataField>
<dataFormToolkit:DataField>
<TextBox Text="Test3" />
</dataFormToolkit:DataField>
</StackPanel>
</DataTemplate>
</dataFormToolkit:DataForm.EditTemplate>
</dataFormToolkit:DataForm>
<!-- This works. -->
<dataFormToolkit:DataForm x:Name="DataForm2"/>
</StackPanel>
</Grid>
To make the second DataForm work, I simply created a Person class, and put the following in Home.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Person client = new Person { Age = 10, DateOfBirth = new DateTime(1980, 10, 20), FirstName = "John", LastName = "Doe" };
DataForm2.CurrentItem = client;
}
You can see what happens when I run the application:
Does anyone know what's wrong? Thank you in advance.
To get something to appear I had to add:
DataForm.CurrentItem = client;
to the code.
This just displayed three text boxes with no labels and the entries "Test1", "Test2" and "Test3". Is this what you were expecting?
The Silverlight Toolkit samples page has an example of a template driven data form and it's XAML looks like this:
<dataform:DataForm x:Name="dataForm" ItemsSource="{Binding}" HorizontalAlignment="Left" MinWidth="400" MaxWidth="500" Margin="4" Grid.Column="1">
<dataform:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<dataform:DataField>
<TextBox Text="{Binding FirstName, Mode=TwoWay}" />
</dataform:DataField>
<dataform:DataField>
<TextBox Text="{Binding Email, Mode=TwoWay}" />
</dataform:DataField>
<dataform:DataField>
<TextBox Text="{Binding Phone, Mode=TwoWay}" />
</dataform:DataField>
<dataform:DataField Label="Calendar">
<controls:Calendar></controls:Calendar>
</dataform:DataField>
</StackPanel>
</DataTemplate>
</dataform:DataForm.EditTemplate>
</dataform:DataForm>
And there's the line:
DataContext = Contact.People;
in the code behind. (The class People is defined elsewhere as far as I can work out)
I also found it quite surprising that you need to bind to something before the form will even appear.
If you're trying to bind to a single item you need to do this :
CurrentItem="{Binding Customer}"
or - if you're in a user control, just
CurrentItem="{Binding}"
and then in the parent control
<my:AddressControl DataContext="{Binding Customer}"/>
Here's the full dataform:
<dt:DataForm Name="dfAddress" AutoGenerateFields="False" CurrentItem="{Binding}">
<dt:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<dt:DataField Label="First Name">
<TextBox Text="{Binding FirstName, Mode=TwoWay}" Style="{StaticResource FieldTextBoxStyle}" HorizontalAlignment="Stretch" IsReadOnly="False" HorizontalContentAlignment="Stretch" />
</dt:DataField>
<dt:DataField Label="Last Name">
<TextBox Text="{Binding LastName, Mode=TwoWay}" Style="{StaticResource FieldTextBoxStyle}" HorizontalContentAlignment="Stretch" />
</dt:DataField>
</StackPanel>
</DataTemplate>
</dt:DataForm.EditTemplate>
</dt:DataForm>
You could give the CurrentItem="" in xaml. In this way, you dont need to actual bind it to anything and at the same time, work on the dataform looks :)

Resources