Пользовательский курсор мыши Silverlight без холста в качестве корня? - PullRequest
1 голос
/ 18 октября 2010

Можно ли использовать пользовательский указатель мыши (изображение в формате png), без с Canvas в качестве корневого элемента?С Canvas в качестве пользователя root работает мышь ( как здесь ), но, к сожалению, я использую несколько пользовательских элементов управления, которые не работают в такой конфигурации: (

Спасибо! Palantir

1 Ответ

3 голосов
/ 20 октября 2010

Вы не можете отказаться от использования Canvas, но это не значит, что вы должны соблюдать то, как Canvas упорядочивает вещи.

Я создал несколько вариантов поведения, которые могут быть вам полезны.

Первый следующий:

[TypeConstraint(typeof(Canvas))]
public class MouseCursorAction : TargetedTriggerAction<UIElement>
{

    protected override void Invoke(object parameter)
    {
    }

    protected override void OnAttached()
    {
        var canvas = AssociatedObject as Canvas;
        if (canvas == null) { return; }
        canvas.MouseMove += new MouseEventHandler(canvas_MouseMove);
        canvas.MouseEnter += new MouseEventHandler(canvas_MouseEnter);
        canvas.MouseLeave += new MouseEventHandler(canvas_MouseLeave);
    }

    void canvas_MouseLeave(object sender, MouseEventArgs e)
    {
        Target.Visibility = Visibility.Collapsed;
    }

    void canvas_MouseEnter(object sender, MouseEventArgs e)
    {
        Target.Visibility = Visibility.Visible;
    }

    void canvas_MouseMove(object sender, MouseEventArgs e)
    {
        var canvas = sender as Canvas;
        var positionInCanvas = e.GetPosition(canvas);
        Canvas.SetTop(Target, positionInCanvas.Y);
        Canvas.SetLeft(Target, positionInCanvas.X);
    }
}

С этим поведением вы можете конвертировать любой UIElement в вашем курсоре мыши. Просто установите его на холст и выберите цель, которой вы хотите, чтобы курсор мыши был.

Теперь, чтобы решить ваши проблемы с макетом, я создал другое поведение:

[TypeConstraint(typeof(Canvas))]
public class FillCanvasAction : TargetedTriggerAction<FrameworkElement>
{

    protected override void Invoke(object parameter)
    {
    }

    protected override void OnAttached()
    {
        var canvas = AssociatedObject as Canvas;
        if (canvas == null) { return; }
        canvas.SizeChanged += new SizeChangedEventHandler(Target_SizeChanged);
    }

    void Target_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        var element = Target;
        if (element == null) { return; }

        var canvas = sender as Canvas;

        element.Width = canvas.ActualWidth;
        element.Height = canvas.ActualHeight;
        Canvas.SetTop(element, 0);
        Canvas.SetLeft(element, 0);
    }
}

Это поведение при подключении к родительскому холсту изменяет размер целевого FrameworkElement (например, Grid) до размера родительского холста. Это означает, что вы можете создать свой собственный макет внутри этого FrameworkElement, не беспокоясь о том, как Canvas обрабатывает расположение.

Тогда в вашем XAML вы можете сделать что-то вроде этого:

<Grid x:Name="LayoutRoot" Cursor="None">
    <Canvas x:Name="canvas" Background="Black">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter">
                <local:MouseCursorAction TargetObject="{Binding ElementName=cursorImage}"/>
            </i:EventTrigger>
            <i:EventTrigger>
                <local:FillCanvasAction TargetObject="{Binding ElementName=grid}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <Grid x:Name="grid" Background="White" Width="600" Height="400">
            <!-- Create your layout here -->
        </Grid>
        <Image x:Name="cursorImage" Height="50" Width="50" Source="mouse_cursor.png"/>
    </Canvas>
</Grid>

Полный рабочий код можно получить по адресу здесь

Отказ от ответственности: строго говоря, это поведение должно быть реализовано с использованием слабой обработки событий, чтобы избежать утечек памяти; однако эта реализация выходит за рамки этого ответа. Вы можете найти больше информации о слабой обработке событий и о том, понадобится она вам или нет для вашего проекта на этом сайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...