8

我无法从其他程序集中引用 xaml 中的类。

在同一个解决方案中,我有两个项目。一种称为 Controls(保存用户控件),另一种称为 DataBinding(保存转换器/验证规则)。在控件中,我尝试在 xaml 中引用验证规则:

<Binding.ValidationRules>
   <databind:Validators.FileExistsRule />
</Binding.ValidationRules>

我的项目引用了包含我的类的项目。我在我的 Control.xaml 的顶部添加了这个声明:

xmlns:databind="clr-namespace:GuiParts.DataBinding;assembly=DataBinding"

但是,当我编译时,我得到一个错误:

The tag 'Validators.FileExistsRule' does not exist in XML namespace 'clr-namespace:GuiParts.DataBinding;assembly=DataBinding'.

该类肯定存在,我可以在后面的代码中毫无问题地调用它,但不能通过 xaml。如果我将班级转移到同一个项目,我再次没有问题。我在这里看到了其他问题,并尝试了以下方法:

  1. 清理和重建所有相关项目
  2. 确保所有项目都针对相同版本的 .Net(4.0,完整配置文件)
  3. 从命名空间定义的末尾删除“程序集”定义。

以上都没有奏效。关于我哪里出错的任何建议?

编辑

我的 FileExists 验证器:

namespace GuiParts.DataBinding.Validators
{
   /// <summary>
   /// Validates that the file with the specified name exists
   /// </summary>
   public class FileExistsRule : ValidationRule
   {
      public override ValidationResult Validate(object value, CultureInfo cultureInfo)
      {
         ValidationResult res = null;
         res = ( ! File.Exists((string)value))
                  ? new ValidationResult(false, "File does not exist")
                  : new ValidationResult(true, null);
         return res;
      }
   }
}

我可以在后面的代码中调用以下代码而不会出现任何错误:

new GuiParts.DataBinding.Validators.FileExistsRule();

所以我得到了我的命名空间等正确的。

4

3 回答 3

5

尝试这个:

xmlns:databind="clr-namespace:GuiParts.DataBinding.Validators;assembly=DataBinding"

<Binding.ValidationRules>    
    <databind:FileExistsRule />    
</Binding.ValidationRules> 
于 2012-07-17T19:32:12.100 回答
3

虽然我不确定您遇到的问题是什么,但您也可以为您的程序集和 CLR 命名空间创建一个更友好的命名空间定义。事实上,我使用这种技术将各种名称空间组合到一个 XML 名称空间中……您可以使用 theXmlnsPrefixAttributeXmlnsDefinitionAttributes 来实现这一点。

例如:

[assembly: XmlnsPrefix("http://my.xml.namespace.com/", "databind")]
[assembly: XmlnsDefinition("http://my.xml.namespace.com/",
    "GuiParts.DataBinding")]
[assembly: XmlnsDefinition("http://my.xml.namespace.com/",
    "GuiParts.DataBinding.Validators")]

然后,当您想在 xaml 中引用 xmlnamespace 时,您只需执行以下操作:

xmlns:databind="http://my.xml.namespace.com/"

请注意,我使用 ReSharper,但我确信这在 Visual Studio 中也很自然。如果您不输入 xmlns 导入并尝试使用命名空间中的对象,那么当您解析它时,它将自动使用具有指定前缀的更友好的命名命名空间。此外,它非常好,可以帮助您避免 xml 命名空间和 clr 命名空间之间存在 1:1 的关系,因为您可以将多个 clr 命名空间映射到单个 xml 命名空间。

同样,我不确定您遇到的具体问题是什么,但这可能会解决它并且比使用 clr-namespaces 和程序集信息更好。只要确保想出一些独特的东西,这样您就不会遇到 xmlns 冲突,否则您将不得不回到 clr/程序集命名空间。


哦,还有最后一件事……如果您希望在您的 xml 命名空间命名方案中使用版本控制(您应该这样做),不必担心为了向后兼容而锁定自己。如果您更新外部程序集以映射到较新的 xml 名称空间,您始终可以使用XmlnsCompatibleWithAttribute确保使用旧的友好名称空间的代码不会中断。

例如,如果您最初将程序集指向 2012 命名空间,然后将其切换到 2013 命名空间,因为您更新了程序集......

// Previous Assembly version
//[assembly: XmlnsDefinition("http://schemas.xyzcorp.com/wpf/2012",
//    "Xyz.Databinding")]

[assembly: XmlnsCompatibleWith("http://schemas.xyzcorp.com/wpf/2012",
    "http://schemas.xyzcorp.com/wpf/2013")]
[assembly: XmlnsDefinition("http://schemas.xyzcorp.com/wpf/2013",
     "Xyz.Databinding")]
于 2012-07-17T19:55:40.767 回答
3
  1. 您的目标程序集中的班级是公开的吗?
  2. 验证器中的字段是公开的吗?
  3. 您的命名空间 GuiParts.DataBinding 是否正确?
于 2012-07-17T19:17:36.777 回答