如何在Silverlight 3.0中将Grid的Cursor属性绑定到我的ViewModel的属性?

4

我试图将IsLoading属性绑定到UI的LayoutRoot网格的Cursor属性。当该属性显示正在加载时,我希望主应用程序光标变成沙漏。

我按以下方式绑定属性:

<Grid Cursor="{Binding IsLoading, Converter={StaticResource CursorConverter}}">

关键字“CursorConverter”将映射到资源中的BoolToCursorConverter。转换器代码如下:
public class BoolToCursorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter == null)
            return ((bool)value == true) ? Cursors.Wait : Cursors.Arrow;
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Cursor cursor = value as Cursor;
        if (cursor != null)
            return cursor == Cursors.Wait ? true : false;
        return false;
    }
}

当我尝试运行时,出现了XamlParseException错误"字典中没有提供的键"。

非常感谢您的任何帮助。

1个回答

6

为什么会出现错误

您的资源属性中是否有类似以下内容的东西?

<local:BoolToCursorConverter x:Key="CursorConverter" />

如果不是这个问题,那么就是其他问题了,但我猜你已经知道了。如果是这种情况,我怀疑你将它放在了适用于的GridResources属性中。这就是为什么找不到它的原因。 StaticResource会在Xaml解析时立即解析。因此,在使用之前,必须将任何键加载到资源字典中。Xaml解析器不知道Grid的Resources属性的内容,因为它还没有处理它。因此:
<UserControl>
   <Grid Cursor="{Binding IsLoading, Converter={StaticResource CursorConverter}}">
     <Grid.Resources>
       <local:BoolToCursorConverter x:Key="CursorConverter" />
     </Grid.Resources>
     <!-- Contents here -->
   </Grid>
</UserControl>

将会失败。而:

<UserControl>
   <UserControl.Resources>
     <local:BoolToCursorConverter x:Key="CursorConverter" />
   </UserControl.Resources >
   <Grid Cursor="{Binding IsLoading, Converter={StaticResource CursorConverter}}">
     <!-- Contents here -->
   </Grid>
</UserControl>

至少不会找不到转换器。

实际需要做的事情

我提供上述内容来回答你的问题,但我可以看出这并没有真正帮到你。你不能像这样绑定Cursor属性。(它不公开标识符字段,Xaml使用NameOfThing+“Property”约定来查找作为绑定属性的DependencyProperty的字段)。

解决方案是创建一个附加属性:

public class BoolCursorBinder
{
    public static bool GetBindTarget(DependencyObject obj) { return (bool)obj.GetValue(BindTargetProperty); }
    public static void SetBindTarget(DependencyObject obj, bool value) { obj.SetValue(BindTargetProperty, value); }

    public static readonly DependencyProperty BindTargetProperty =
            DependencyProperty.RegisterAttached("BindTarget", typeof(bool), typeof(BoolCursorBinder), new PropertyMetadata(false, OnBindTargetChanged));

    private static void OnBindTargetChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = sender as FrameworkElement;
        if (element != null)
        {
            element.Cursor = (bool)e.NewValue ? Cursors.Wait : Cursors.Arrow;
        }
    }
}

现在,您可以像这样进行绑定:-
 <Grid local:BoolCursorBinder.BindTarget="{Binding IsLoading}">

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接