Есть ли способ имитировать MouseOver в WPF? - PullRequest
0 голосов
/ 25 мая 2010

Я работаю над элементом управления ссылками в WPF, который соответствует тексту со значком ссылки в руководстве по Windows UX. Я хочу иметь текст в гиперссылке, которая появляется справа от изображения.

В моем случае я начал с использования TextBlock, который содержал гиперссылку, которая затем содержала мое изображение и некоторый текст.

<TextBlock>
    <Hyperlink>
        <Rectangle Height="16"
                   Width="16"
                   Fill="{StaticResource MyIconBrush}"
                   Stretch="UniformToFill"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Left" />
        <Run>My link text</Run>
    </Hyperlink>
</TextBlock>

Проблема с этим, однако, заключалась в том, что изображение, которое было выше моего текста, создавало эффект выравнивания текста по низу. К сожалению, я не нашел способа управлять вертикальным выравниванием в TextBlock или в Гиперссылке, поэтому я прибег к попытке альтернативного макета, где Гиперссылка и Прямоугольник, представляющие мой векторный значок, разделены, чтобы заставить их выровняйте правильно, как показано ниже.

<StackPanel Orientation="Horizontal">
    <Rectangle Height="16"
               Width="16"
               Fill="{StaticResource MyIconBrush}"
               Stretch="UniformToFill"
               VerticalAlignment="Center"
               HorizontalAlignment="Left" />
    <TextBlock VerticalAlignment="Center"><Hyperlink>My link text<Hyperlink></TextBlock>
</StackPanel>

Проблема с этим, однако, заключается в том, что теперь, когда мой Icon и моя гиперссылка разделены, я не вижу, как MouseOver выглядит как моя ссылка, когда я нахожу курсор мыши на мой значок, и наоборот. Кроме того, в моей гиперссылке есть опция для подключения Команды, а для Rectangle и StackPanel - нет, поэтому, если я использую Hyperlink.Command, значок не будет выполнять Команду.

Так что это заставило меня задуматься, как мне имитировать MouseOver для данного элемента управления, например, с помощью флажка, в котором вы получаете эффект MouseOver на поле, когда вы на самом деле наводите курсор на связанный с ним текст. Я знаю, что в мире HTML элемент label имеет атрибут for , который можно использовать, чтобы указать, какой элемент управления он обозначает, который в основном будет выполнять то, что я находясь в поиске. Также я могу представить, что в других сценариях было бы неплохо иметь метку, которая при наведении курсора мыши отображает соответствующее текстовое поле, как если бы указатель мыши был над ним, и, возможно, при щелчке мышью также фокусируется на соответствующем текстовом поле. На данный момент меня интересует, главным образом, как получить метку или элемент, подобный метке в WPF, чтобы он действовал как прокси для данного элемента управления с точки зрения его состояния MouseOver. Также я хотел бы сделать это чисто в XAML, если это возможно.

ОБНОВЛЕНИЕ : Я также попытался выполнить следующее, но безуспешно. Я получаю желаемое изображение, но ссылки под значком оказалось недостаточно для получения событий мыши. Я полагаю, что тесты попадания работают только тогда, когда мышь находится над отображаемым текстом, независимо от заполнения элемента управления.

<Grid>
    <Rectangle Height="16"
               Width="16"
               Fill="{StaticResource MyIconBrush}"
               Stretch="UniformToFill"
               HorizontalAlignment="Left"
               VerticalAlignment="Center"
               IsHitTestVisible="False"
               Focusable="False"/>
    <TextBlock Padding="18,0,0,0"
                VerticalAlignment="Center"><Hyperlink>Configure additional filters...</Hyperlink></TextBlock>
</Grid>

Ответы [ 3 ]

1 голос
/ 25 мая 2010

Использование Run и BaselineAlignment = "Center" приведет к неработающей ссылке. Просто поместите изображение и текстовый блок в горизонтальную панель стека вот так.

<TextBlock> 
    <Hyperlink> 
        <StackPanel Orientation="Horizontal">
            <Rectangle 
                Height="16" Width="16" 
                Fill="{StaticResource MyIconBrush}" 
                Stretch="UniformToFill" VerticalAlignment="Center" HorizontalAlignment="Left" /> 
            <TextBlock 
                Text="My link text" 
                VerticalAlignment="Center"/>
        </StackPanel>
    </Hyperlink>
</TextBlock>

Если вы хотите, чтобы видимый элемент управления реагировал на событие наведения мыши каким-либо иным способом, чем это происходит по умолчанию, вам необходимо переопределить его шаблон элемента управления. Это проще всего сделать, взяв существующий шаблон управления и изменив его в соответствии с вашими потребностями. Например, шаблон управления для флажка можно найти здесь: http://msdn.microsoft.com/en-us/library/ms752319(v=VS.85).aspx Ссылка должна указывать, как изменить фон на другой цвет при наведении курсора, но вы также можете сделать линию под каким-то цветом содержимого, чтобы изменить гиперссылку.

1 голос
/ 26 мая 2010

Элементы пользовательского интерфейса имеют метод RaiseEvent, который можно использовать для имитации событий мыши.

XAML:

<Window x:Class="MouseOverTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <StackPanel>
        <TextBlock>  
            <Hyperlink MouseEnter="OnHyperlinkMouseEnter" Name="_hyperLink">  
                <TextBlock Text="My link text" /> 
            </Hyperlink> 
        </TextBlock>
        <Button Content="Simulate mouse enter" Click="OnButtonClick" />
    </StackPanel>
</Window>

Код:

using System.Windows;
using System.Windows.Input;

namespace MouseOverTest
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void OnButtonClick(object sender, RoutedEventArgs e)
        {
            MouseEventArgs mouseEventArgs = new MouseEventArgs(Mouse.PrimaryDevice, 0);
            mouseEventArgs.RoutedEvent = Mouse.MouseEnterEvent;
            _hyperLink.RaiseEvent(mouseEventArgs);
        }

        private void OnHyperlinkMouseEnter(object sender, MouseEventArgs e)
        {
            MessageBox.Show("Mouse enter");
        }
    }
}
1 голос
/ 25 мая 2010

Первый код - это путь. Вы можете управлять выравниванием Run с помощью BaselineAlignment. Установите Center, и ваша ссылка будет работать так, как вы хотели.

...