WPF使用验证规则动态加载xaml

时间:2014-12-05 10:40:05

标签: c# wpf vb.net

我在WPF中比较新,我遇到了问题 我必须实现一个从数据库中获取UI(xaml)的表单(以及数据)。 这些将在运行时创建的表单中的每一个都将具有不同的控件 虽然我不同意这种做法,但我必须遵循老板的指示 问题在于验证 我们决定使用验证规则 所以我尝试使用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>

加载xaml时出现的错误是

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

就在这一行:

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

注意:c定义为:

xmlns:c="clr-namespace:WpfDynamicTest1"

如何克服此错误?
我遇到了与ControlTemplate和Style类似的错误错误,但我将它们移到了Application.xaml,我的问题解决了。
我可以做一些类似于类的参考吗?

修改:其他信息 我如何加载xaml:
&#34;细胞&#34; form具有以下属性:

 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

因此,当我打电话给表格时,我会这样做:

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

FormCharacteristics填充msUI并加载UI。

2 个答案:

答案 0 :(得分:1)

虽然不确定您是否搜索了以下某些链接,但我希望它们对您有所帮助:

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'.'

修改

基于上面的链接,假设您正在使用XamlReader,我创建了一个示例并且其工作正常。在这种情况下,我发现的原因是,XAML Parser需要ParserContext映射命名空间以在运行时绑定所需的类型。

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>

代码落后(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());
            }
        }
    }

注意

对于绑定验证。,我使用了您提供的相同MSDN代码。

此外,由于我现在不使用VB.NET HAT,我选择C#作为背后的代码!!虽然代码很简单。

答案 1 :(得分:0)

你的AngeRangeRule应该来自ValidationRule。

public class AgeRangeRule : ValidationRule { .... }

您必须覆盖ValidationResult成员:

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