[英]WPF dynamically load xaml with validation rules
I am relatively new in WPF and I face a problem. 我在WPF中相对较新,因此遇到了问题。
I have to implement a form that gets the UI(xaml) from the database (as also the data). 我必须实现一种从数据库(以及数据)中获取UI(xaml)的形式。 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 . 因此,我尝试使用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 加载xaml时出现的错误是
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: 注意:c定义为:
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. 我在ControlTemplate和Style上遇到了类似的错误,但是将它们移到Application.xaml,问题解决了。
Can I do something similar with the reference to the class? 我可以对类进行类似的操作吗?
Edit: Additional Info: How I load the xaml: 编辑:附加信息:我如何加载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. FormCharacteristics填充msUI,并加载UI。
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 在程序运行时编译/执行XAML
WPF – dynamically compile and run event handlers within loose XAML using CodeDom WPF –使用CodeDom在松散的XAML中动态编译和运行事件处理程序
Loading XAML at runtime? 在运行时加载XAML?
Error: 'Cannot create unknown type '{clr-namespace:NameSpace.Properties}Settings'.' 错误:“无法创建未知类型'{clr-namespace:NameSpace.Properties}设置”。
EDIT 编辑
Based on the links above, assuming you are using XamlReader, I created a sample and its working fine. 根据上面的链接,假设您使用的是XamlReader,我创建了一个示例,并且可以正常工作。 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解析器需要ParserContext来映射名称空间以在运行时绑定所需的类型。
Xaml (Dynamic usercontrol to load) Xaml(要加载的动态用户控件)
<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#) 背后的代码(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. 对于绑定验证。,我使用了您提供的相同的MSDN代码。
Also since I am not with the VB.NET HAT now, I choose C# for the code behind!! 另外,由于我现在不使用VB.NET HAT,因此我选择C#作为后面的代码! Though the code is simple enough. 虽然代码很简单。
Your AngeRangeRule should derive from ValidationRule. 您的AngeRangeRule应该从ValidationRule派生。
public class AgeRangeRule : ValidationRule { .... }
And you have to override ValidationResult
member: 而且您必须重写ValidationResult
成员:
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
// Cast value object and check if it is valid
return new ValidationResult(...,...);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.