x:在 XAML 中重新排列元素后,无法解析引用。
在这里,我提出了一个工作代码。只需移动 DataGrid 元素,使其位于按钮元素之后,ContextMenu 中的 MenuItem 和 Button.IsEnabled 中的多重绑定的绑定就会损坏。在 Button.IsEnabled 中,只有多重绑定被破坏。它可以替换为注释块和 x:Reference 在该单个绑定中工作。
两者都抛出 XamlParseException。
- MenuItem 提供 System.Xaml.XamlObjectWriterException 和消息讨论未解析的引用。
- MultiBinding 将 System.Collections.Generic.KeyNotFoundException 作为内部异常。
那么 x:Reference 何时真正解析,为什么当引用的元素位于引用它的元素之后时,只有一些绑定会中断?
这是我的 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>
这是我的隐藏代码(不使用):
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();
}
}
}
这是因为您的资源(Window.Resources)将在引用的实例存在之前首先创建。我会尝试通过DataContext(ViewModel)来解决这个问题。
<Window.DataContext>
<yourNameSpace:YourViewModel x:Name="VieModName" />
</Window.DataContext>
<MenuItem Header="HeadrTxt" Command="{Binding CommandInViewModelCmd}" DataContext="{x:Reference Name=VieModName}" />
自MSDN(http://msdn.microsoft.com/en-us/library/ee795380.aspx)。
x:引用是 XAML 2009 中定义的构造。在 WPF 中,可以使用XAML 2009 功能,但仅适用于未经过 WPF 标记编译的 XAML。标记编译的 XAML 和 XAML 的 BAML 形式当前没有支持 XAML 2009 语言关键字和功能。
WPF 中必须避免x:Reference
。因为此标记扩展是 XAML 语言 (2009) 的最新添加。而且它在 WPF 中并不完全受支持。在Binding
中使用ElementName
而不是x:Reference
。
<Binding Path="SelectedItem"
ElementName="dataGridElement"/>
在MSDN上。