2013-02-01 11 views
10

x:在重新排列XAML中的元素后,引用无法解析。何时x:WPF中的引用已解析,为什么XAML元素顺序会影响它?

这里我提出一个工作代码。只需移动DataGrid元素,以便它在Button元素和ContextMenu中的MenuItem的绑定以及Button.IsEnabled中的MultiBinding的绑定变为中断时使用。在Button.IsEnabled中,仅MultiBinding已损坏。它可以用注释块和x代替:引用在该单个绑定中起作用。

两者都抛出XamlParseException。

  • MenuItem给出System.Xaml.XamlObjectWriterException和消息有关未解决的引用的说明。
  • MultiBinding将System.Collections.Generic.KeyNotFoundException作为内部异常。

那么,什么时候该x:参考实际上解决了,为什么只有一些绑定破坏引用元素后引用它的元素?

这是我的XAML:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:xxx="clr-namespace:WpfApplication1" 
     Title="MainWindow" SizeToContent="WidthAndHeight"> 
    <Window.Resources> 
     <xxx:BoolToVisibleConverter x:Key="boolToVisibleConv"></xxx:BoolToVisibleConverter> 
     <xxx:NullToFalseConverter x:Key="nullToFalseConv"></xxx:NullToFalseConverter> 
     <xxx:NullsOrToFalseConverter x:Key="nullsOrToFalseConv"></xxx:NullsOrToFalseConverter> 
     <ContextMenu x:Key="MyMenu"> 
      <MenuItem 
       Header="Menuitem enabled when row selected" 
       IsEnabled="{Binding 
        Path=SelectedItem, 
        Source={x:Reference dataGridElement}, 
        Converter={StaticResource nullToFalseConv}}" /> 
     </ContextMenu> 
    </Window.Resources> 
    <StackPanel> 
     <DataGrid 
      Name="dataGridElement" 
      IsReadOnly="True" /> 
     <Button 
      Content="Button" 
      ContextMenu="{StaticResource MyMenu}" 
      Visibility="{Binding 
       Path=IsReadOnly, 
       Source={x:Reference dataGridElement}, 
       Converter={StaticResource boolToVisibleConv}}"> 
      <Button.IsEnabled> 
       <!--<Binding 
        Path="SelectedItem" 
        Source="{x:Reference dataGridElement}" 
        Converter="{StaticResource nullToFalseConv}"/>--> 
       <MultiBinding 
        Converter="{StaticResource nullsOrToFalseConv}"> 
        <Binding 
         Path="SelectedItem" 
         Source="{x:Reference dataGridElement}"/> 
        <Binding 
         Path="SelectedItem" 
         Source="{x:Reference dataGridElement}"/> 
       </MultiBinding> 
      </Button.IsEnabled> 
     </Button> 
    </StackPanel> 
</Window> 

这是我后面的代码(不usings):

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 
    public class BoolToVisibleConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value == null || (bool)value == false) 
       return System.Windows.Visibility.Hidden; 
      else 
       return System.Windows.Visibility.Visible; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
    public class NullsOrToFalseConverter : IMultiValueConverter 
    { 
     public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      foreach (object val in value) 
      { 
       if (val == null) 
        return false; 
      } 
      return true; 
     } 

     public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
    public class NullToFalseConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return (value != null); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

回答

-2

x:Reference必须在WPF避免。因为这个标记扩展是XAML语言(2009)的最新增加。它并不完全支持WPF。在Binding中使用ElementName而不是x:Reference

<Binding Path="SelectedItem" 
     ElementName="dataGridElement"/> 

MSDN

+1

问题是,有时ElementName找不到该元素。这就是我首先使用x:Reference的原始原因。据我所知x:引用是一种解决方法,它不起作用时ElementName。他们都不工作的情况如何?例如,在这种情况下,使用ElementName适用于Button.IsEnabled中的MultiBinding,但不适用于启用上下文菜单项。 – user2032138

+0

@ user2032138它在MSDN文章中解释说,“但仅适用于不是WPF标记编译的XAML。” –

+1

所以在这种情况下,当XAML描述应用程序的主UI时,使用x:不支持引用? – user2032138

1

我想这是因为你的资源(Window.Resources)将在被引用的实例存在之前被首先创建。我会尝试通过DataContext(ViewModel)来解决这个问题。

<Window.DataContext> 
     <yourNameSpace:YourViewModel x:Name="VieModName" /> 
    </Window.DataContext> 
<MenuItem Header="HeadrTxt" Command="{Binding CommandInViewModelCmd}" DataContext="{x:Reference Name=VieModName}" /> 
相关问题