Why you get that error
Do you have something like this in the content of a Resources property?
<local:BoolToCursorConverter x:Key="CursorConverter" />
If not then that's what is wrong but I'm guessing you already do.
In that case you I suspect you have placed it in the Resources
property of the Grid
it applies to. That would be why it can not be found. StaticResource
are resolved immediately as the Xaml is parsed. Hence any key used must already be loaded into a resource dictionary prior to use. The Xaml parser knows nothing of the contents of the Grid's Resources
property because it hasn't processed it yet. Hence:-
<UserControl>
<Grid Cursor="{Binding IsLoading, Converter={StaticResource CursorConverter}}">
<Grid.Resources>
<local:BoolToCursorConverter x:Key="CursorConverter" />
</Grid.Resources>
<!-- Contents here -->
</Grid>
</UserControl>
will fail. Where as:-
<UserControl>
<UserControl.Resources>
<local:BoolToCursorConverter x:Key="CursorConverter" />
</UserControl.Resources >
<Grid Cursor="{Binding IsLoading, Converter={StaticResource CursorConverter}}">
<!-- Contents here -->
</Grid>
</UserControl>
would at least not fail in finding the converter.
What you actually need to do
I've presented the above to answer your question but I can see it doesn't really help you. You can't bind to the Cursor property like this. (It doesn't expose a public identifier field, Xaml uses the NameOfThing + "Property" convention to find a field that is the DependencyProperty
for the property being bound).
The solution is to create an Attached property:-
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;
}
}
}
Now you can actually do the binding like this:-
<Grid local:BoolCursorBinder.BindTarget="{Binding IsLoading}">