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

时间:2010-02-04 21:09:50

标签: c# silverlight xaml silverlight-3.0

我正在尝试将IsLoading属性绑定到UI的LayoutRoot Grid的Cursor属性。我试图让主app光标变成沙漏,只要属性说它正在加载。

我按如下方式绑定了该属性:

<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 个答案:

答案 0 :(得分:6)

为什么会出现该错误

您在Resources属性的内容中是否有类似的内容?

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

如果没有,那就错了,但我猜你已经这么做了。

在这种情况下,我怀疑您已将其放在它适用的Resources的{​​{1}}属性中。这就是为什么它找不到的原因。解析Xaml时会立即解析Grid。因此,在使用之前,所使用的任何密钥必须已经加载到资源字典中。 Xaml解析器不知道Grid的StaticResource属性的内容,因为它尚未处理它。因此: -

Resources

会失败。其中: -

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

至少不会失败找到转换器。

您实际需要做什么

我已经提出上述问题来回答你的问题,但我发现它并没有真正帮助你。您不能像这样绑定到Cursor属性。 (它不公开公共标识符字段,Xaml使用 NameOfThing +“Property”约定来查找被绑定属性的<UserControl> <UserControl.Resources> <local:BoolToCursorConverter x:Key="CursorConverter" /> </UserControl.Resources > <Grid Cursor="{Binding IsLoading, Converter={StaticResource CursorConverter}}"> <!-- Contents here --> </Grid> </UserControl> 字段。

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

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;
        }
    }
}