1

I am relatively new in WPF and I face a problem.
I have to implement a form that gets the UI(xaml) from the database (as also the data). Each of these forms that will be created at runtime they will have different controls.
Although I disagree with this approach I have to follow my boss directions.
The problem is with the validation.
We decided to do it with Validation Rules.
So I tried to implemented the basic example with the AgeRangeRule.

<TextBox Name="textBox1" Width="50" FontSize="15" Validation.ErrorTemplate="{StaticResource validationTemplate}" Style="{StaticResource textBoxInError}" Grid.Row="1" Grid.Column="1" Margin="2"> <TextBox.Text> <Binding Path="Age" Source="{StaticResource ods}" UpdateSourceTrigger="PropertyChanged" > <Binding.ValidationRules> <c:AgeRangeRule Min="21" Max="130"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> 

The error that I get when I load the xaml is

Additional information: 'Cannot create unknown type '{clr-namespace:WpfDynamicTest1}AgeRangeRule'.' 

And is in this line:

 <c:AgeRangeRule Min="21" Max="130"/> 

Note: c is defined as:

xmlns:c="clr-namespace:WpfDynamicTest1" 

How can I overcome this error?
I faced similar errors with the ControlTemplate and Style for the errors but I moved them to the Application.xaml and my problems solved.
Can I do something similar with the reference to the class?

Edit: Additional Info: How I load the xaml:
The "cell" form has these properties:

 Public Property FormId() As Integer Get Return miFormId End Get Set(ByVal value As Integer) miFormId = value FormCharacteristics(value) End Set End Property Public Property UI() As String Get Return msUI End Get Set(ByVal value As String) msUI = value Dim rootObject As DependencyObject = XamlReader.Parse(value) Me.Content = rootObject End Set End Property 

So when I call the form I do this:

 Dim winD As New winDynamic winD.FormId = 4 winD.Show() 

The FormCharacteristics fills msUI and UI is loaded.

2
  • Are you sure that you ValidationRule "AgeRangeRule " is correctly defined in namespace named WpfDynamicTest1 ? Commented Dec 5, 2014 at 10:47
  • Yes, if I don't load the xaml from DB at runtime and have it as usual the code is working Commented Dec 5, 2014 at 10:50

2 Answers 2

1

Though not sure if you search through some of the following links but i hope they could be of help to you:

Compile/Execute XAML during program runtime

WPF – dynamically compile and run event handlers within loose XAML using CodeDom

Loading XAML at runtime?

Error: 'Cannot create unknown type '{clr-namespace:NameSpace.Properties}Settings'.'

EDIT

Based on the links above, assuming you are using XamlReader, I created a sample and its working fine. In this case, the reason I found is, the XAML Parser need the ParserContext to map the namespaces to bind the required types at run time.

Xaml (Dynamic usercontrol to load)

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300" xmlns:c="clr-namespace:WpfApplication1"> <UserControl.Resources> <c:MyDataSource x:Key="ods"/> <ControlTemplate x:Key="validationTemplate"> <DockPanel> <TextBlock Foreground="Red" FontSize="20">!</TextBlock> <AdornedElementPlaceholder/> </DockPanel> </ControlTemplate> <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style> </UserControl.Resources> <StackPanel> <TextBox Name="textBox1" Width="50" FontSize="15" Validation.ErrorTemplate="{StaticResource validationTemplate}" Style="{StaticResource textBoxInError}" Grid.Row="1" Grid.Column="1" Margin="2"> <TextBox.Text> <Binding Path="Age" Source="{StaticResource ods}" UpdateSourceTrigger="PropertyChanged" > <Binding.ValidationRules> <c:AgeRangeRule Min="21" Max="130"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <Button x:Name="btnDynamic" Width="150" Height="30" Content="Click Me"/> </StackPanel> </UserControl> 

Code behind (C#)

 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); LoadXAML(); } public void LoadXAML() { try { using (StreamReader xamlStream = new StreamReader(@"C:\WpfApplication1\WpfApplication1\DynamicWindow.xaml")) { var context = new ParserContext(); context.XamlTypeMapper = new XamlTypeMapper(new string[] { }); context.XmlnsDictionary.Add("c", "clr-namespace:WpfApplication1"); context.XamlTypeMapper.AddMappingProcessingInstruction("clr-namespace:WpfApplication1", "WpfApplication1", "WpfApplication1"); string xamlString = xamlStream .ReadToEnd(); DependencyObject rootObject = XamlReader.Parse(xamlString, context) as DependencyObject; cntControl.Content = rootObject; //cntControl is a content control I placed inside MainWindow } } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); } } } 

Note

For the Binding Validation., I used same MSDN code you provided.

Also since I am not with the VB.NET HAT now, I choose C# for the code behind!! Though the code is simple enough.

Sign up to request clarification or add additional context in comments.

2 Comments

@Nianios What happen if you change: xmlns:c="clr-namespace:WpfDynamicTest1" To xmlns:c="clr-namespace:WpfDynamicTest1;assembly:WpfDynamicTest1OrWhatEverAssemblyItIsIn"
Hm, I code in VB and when I add this I get a lot of errors. The first one is The URI "clr-namespace:BindValidation;assembly:BindValidation" is not a valid namespace identifier.
0

Your AngeRangeRule should derive from ValidationRule.

public class AgeRangeRule : ValidationRule { .... }

And you have to override ValidationResult member:

public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { // Cast value object and check if it is valid return new ValidationResult(...,...); } 

3 Comments

This is not relevant to the question. I followed the example. SO I did all these. Now I am trying to load the xaml at runtime.
Strange. I indeed tried to have a class AgeRangeRule and I got the error that you had. And when I derive it from ValidationRule and implemented the Validate, your code sample ran fine.
So are you saying that you are load the xaml at runtime and it works? Because mine is running fine when I don't load the xaml at runtime , but not when I load it at runtime

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.