Как привязать свойство курсора сетки к свойству моей модели представления в Silverlight 3.0? - PullRequest
4 голосов
/ 05 февраля 2010

Я пытаюсь привязать свойство IsLoading к свойству Cursor сетки LayoutRoot моего пользовательского интерфейса. Я пытаюсь, чтобы курсор основного приложения становился песочными часами, когда свойство сообщает, что оно загружается.

Я связываю свойство следующим образом:

<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 голосов
/ 06 февраля 2010

Почему вы получаете эту ошибку

Есть ли у вас что-то подобное в содержании свойства Resources?

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

Если нет, то это то, что не так, но я предполагаю, что вы уже делаете.

В этом случае вы, я подозреваю, поместили его в Resources свойство Grid, к которому он относится. Вот почему это не может быть найдено. 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 + «Свойство» для поиска поля, которое является DependencyProperty для привязываемого свойства).

Решением является создание свойства Attached: -

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}">
...