x:引用在设计模式下找不到x:Name - 编译并运行正常

时间:2014-10-20 15:03:57

标签: c# wpf xaml datagrid markup

这是一个设计时问题。代码编译并运行后,将传入正确的值。

1 - 使用作为ConverterParameter通过x:Name引用数据网格(根据MSDN信息,这是正确的)。 2 - 不能使用与ElementName的绑定,因为ConverterParameter不是依赖项属性。我想我可以创建一个依赖属性,它似乎没有必要,因为在某个时间点,x:引用已经解决..只是在设计时没有解决。

所以我有以下代码。这是一个模板,允许对过滤的列标题进行着色,因此它们在视觉上对用户来说是显而易见的:

<Converters:BGConverter x:Key="BackgroundConverter"/>
<Style TargetType="DataGridColumnHeader">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Border BorderBrush="Black" BorderThickness="1" Width="150">
                    <StackPanel x:Name="testtest" Orientation="Horizontal"
                        Background="{Binding Converter={StaticResource BackgroundConverter}, ConverterParameter={x:Reference TestListView}}">                                        
                    <Label Width="90" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridColumnHeader}},Path=Column.Header}"
                                Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                    <Button Content="Ok" Padding="12,0,12,0"  HorizontalAlignment="Right" VerticalAlignment="Center" Margin="20,0,0,0"/>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>      

问题在于“ConverterParameter =”{x:Reference TestListView}“部分。标记不编译,”GUI“仅显示”抛出了异常。 XamlObjectWriterException:未解析的引用'TestListView'。

同样,如果我单步执行代码并实际运行程序,则每个标头实际上都会正确传入转换器,并确定标题列颜色并正确显示。

Datagrid(引用的对象)声明如下(部分,不需要borderthickness或headersvisibility等等):

<DataGrid x:Name="TestListView" />

有没有办法修复设计器,以便它可以确定并找到x:Name?我读过2009年的文章说x:参考是新的,实际上并不是Xaml的一部分,但那是2009年,差不多是2015年。在6年内,这应该已被容纳或删除。

有关如何让编译器识别x:Name而不发疯并将其声明为静态或创建依赖属性的任何建议?由于它只是标记,我可以按原样使用它,它只会让我的强迫症疯狂。

1 个答案:

答案 0 :(得分:3)

编译的Xaml中没有正式支持

x:Reference,它仍然基于Xaml2006规范。由于它是作为标记扩展而不是语言增强实现的,它在某些情况下仍会在运行时工作(尽管不是全部),但是设计者不支持它,并且没有办法使它在某种程度上不能扩展设计师自己。

您可以使用相同的服务实现与x:Reference执行相同任务的自定义标记扩展,但在缺少所需服务的情况下(例如,在设计器中运行时),它会无声地失败:

[ContentProperty("Name")]
public class NameReferenceExtension : MarkupExtension
{
    [ConstructorArgument("name")]
    public string Name { get; set; }

    public NameReferenceExtension() {}

    public NameReferenceExtension(string name)
    {
        this.Name = name;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (serviceProvider == null)
            throw new ArgumentNullException("serviceProvider");

        var xamlNameResolver = serviceProvider.GetService(typeof(IXamlNameResolver))
                               as IXamlNameResolver;
        if (xamlNameResolver == null)
            return null; // fail silently

        if (string.IsNullOrEmpty(this.Name))
            throw new InvalidOperationException(
                "Name is required when using NameReference.");

        var resolved = xamlNameResolver.Resolve(this.Name);
        if (resolved == null)
            resolved = xamlNameResolver.GetFixupToken(new[] { this.Name }, true);

        return resolved;
    }
}