wpf - 鼠标悬停在图像控件上时显示弹出窗口

标签 wpf image wpf-controls popup

我想在鼠标悬停在图像控件上时显示弹出窗口。所以我创建了控制模板,它看起来像这样:

        <ControlTemplate x:Key="AvatarImageTemplate" TargetType="{x:Type Image}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>

                <HERE I WANT IMAGE SOURCE  Grid.Row="0"/>
                <Popup  IsOpen="False" 
                            Name="OponentImagePopUp"                               
                            AllowsTransparency="True"
                            PopupAnimation="Slide"
                            HorizontalOffset="-35"
                            VerticalOffset="0"
                            Grid.Row="1">
                    <Border BorderThickness="1" 
                                BorderBrush="Black">
                        <Grid  Height="350" MinWidth="350">
                            <Grid.Background>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.3">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="LightGray" Offset="0"/>
                                        <GradientStop Color="WhiteSmoke" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </Grid.Background>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="75"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"></RowDefinition>
                            </Grid.RowDefinitions>

                            <Border BorderThickness="1" 
                                    BorderBrush="Black"
                                    Background="White"
                                    Margin="4,4,4,4"
                                    Grid.Column="0">
                                <Image Margin="2,2,2,2">
                                    <Image.Source >
                                        <MultiBinding Converter="{StaticResource avatarConverter}">
                                            <Binding Path="ProfilePhoto"></Binding>
                                            <Binding Path="StatusInfo.IsLogged"></Binding>
                                        </MultiBinding>
                                    </Image.Source>
                                </Image>
                            </Border>
                        </Grid>
                    </Border>
                </Popup>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="OponentImagePopUp" Property="IsOpen" Value="True" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

我有两个问题:
  • 我不知道如何访问控制模板中的图像源
  • 此外,如果我尝试在图像控件上创建样式并设置属性模板 -> 图像控件没有属性模板。

  • 我的目标是显示具有相同图像的弹出窗口,只是更大。

    编辑:

    我创建了简单的控制,作为 Glazkov 先生的建议,它具有图像控制,这里是:
    <UserControl x:Class="Spirit.Controls.AvatarImageControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <Image x:Name="SmallImage"
                Source="{Binding ElementName=root, Path=ImageSource}"
                Stretch="Fill"/>
        </Grid>
    </UserControl>
    

    后面的代码是一样的:
      public partial class AvatarImageControl : UserControl
        {
            public AvatarImageControl()
            {
                InitializeComponent();
            }
    
            public ImageSource ImageSource
            {
                get { return (ImageSource)GetValue(ImageSourceProperty); }
                set { SetValue(ImageSourceProperty, value); }
            }
    
            public static readonly DependencyProperty ImageSourceProperty =
                DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(AvatarImageControl), new UIPropertyMetadata(null));
    
        }
    

    我尝试在 View 中使用此控件:
    <Grid Background="#99CCFF"  Margin="4,4,4,4">
          <Controls:AvatarImageControl ImageSource="{Binding Path=Oponent.Info.ProfilePhoto,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
    

    我将 Uri 的属性类型绑定(bind)到 AvatarImageControl 的 ImageSource。

    我做什么坏事?

    我也在用户控制中尝试这个:
    <Grid>
        <Image x:Name="SmallImage"
            Source="{Binding Path=ImageSource, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
            Stretch="Fill"/>
    </Grid>
    

    结果是一样的。

    我在 View 中使用用户控件,我从 Uri 的 View 模型类型绑定(bind) ImageSource 属性。没有其他的。

    编辑 2:
    Glazkov 先生的代码产生异常:
    {"Set property 'System.Windows.Controls.Primitives.Popup.IsOpen' threw an exception."}
    {"A TwoWay or OneWayToSource binding cannot work on the read-only property 'IsMouseOver' of type 'System.Windows.Controls.Image'."}
    StackTrace:
       at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at Spirit.Controls.AvatarImageControl.InitializeComponent() in c:\Users\Jan\Documents\Visual Studio 2010\Projects\BACKUP\Pokec__Messenger\Spirit_Caliburn_Micro_v1.0\Controls\AvatarImageControl.xaml:line 1
       at Spirit.Controls.AvatarImageControl..ctor() in C:\Users\Jan\Documents\Visual Studio 2010\Projects\BACKUP\Pokec__Messenger\Spirit_Caliburn_Micro_v1.0\Controls\AvatarImageControl.xaml.cs:line 24
    

    解决方案是:
     <Popup IsOpen="{Binding ElementName=SmallImage, Path=IsMouseOver, Mode=OneWay}">
    

    设置单向绑定(bind)模式。

    它运作良好。

    感谢 Glazkov 先生的帮助。

    最佳答案

    您不能为图像控件定义控件模板,因为它不是从 Control 派生的。 ,因此它没有控制模板。它只是在 OnRender 方法中呈现自己。

    您可以做的是创建一个具有一个依赖属性 ImageSource 的用户控件。 .这是此控件的 XAML:

    <UserControl x:Class="AvatarImage"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 x:Name="root">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
    
            <Image x:Name="SmallImage"
                   Source="{Binding ElementName=root, Path=ImageSource}"
                   Grid.Row="0" />
            <Popup IsOpen="{Binding ElementName=SmallImage, Path=IsMouseOver, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
                   Name="OponentImagePopUp"
                   AllowsTransparency="True"
                   PopupAnimation="Slide"
                   HorizontalOffset="-35"
                   VerticalOffset="0"
                   Grid.Row="1">
                <Border BorderThickness="1"
                        BorderBrush="Black">
                    <Grid Height="350"
                          MinWidth="350">
                        <Grid.Background>
                            <LinearGradientBrush StartPoint="0,0"
                                                 EndPoint="0,0.3">
                                <LinearGradientBrush.GradientStops>
                                    <GradientStop Color="LightGray"
                                                  Offset="0" />
                                    <GradientStop Color="WhiteSmoke"
                                                  Offset="1" />
                                </LinearGradientBrush.GradientStops>
                            </LinearGradientBrush>
                        </Grid.Background>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="75"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"></RowDefinition>
                        </Grid.RowDefinitions>
    
                        <Border BorderThickness="1"
                                BorderBrush="Black"
                                Background="White"
                                Margin="4,4,4,4"
                                Grid.Column="0">
                            <Image Margin="2,2,2,2">
                                <Image.Source>
                                    <MultiBinding Converter="{StaticResource avatarConverter}">
                                        <Binding Path="ProfilePhoto"></Binding>
                                        <Binding Path="StatusInfo.IsLogged"></Binding>
                                    </MultiBinding>
                                </Image.Source>
                            </Image>
                        </Border>
                    </Grid>
                </Border>
            </Popup>
        </Grid>
    </UserControl>
    

    这是背后的代码(AvatarImage.xaml.cs):
    public partial class AvatarImage : UserControl
    {
        public AvatarImage() {
            InitializeComponent();
        }
    
        public ImageSource ImageSource {
            get { return (ImageSource)GetValue(ImageSourceProperty); }
            set { SetValue(ImageSourceProperty, value); }
        }
    
        public static readonly DependencyProperty ImageSourceProperty =
            DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(AvatarImage), new UIPropertyMetadata(null));
    }
    

    关于wpf - 鼠标悬停在图像控件上时显示弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4735395/

    相关文章:

    android - 使用包装内容可绘制图像获取 ImageView 位置

    python - 将 RGB 图像转换为灰度图像并在 python 中操作像素数据

    java - 尝试将图像绘制到 JPanel 上

    wpf - Windows Phone 8.1 Tab/滑动控制

    c# - Windows 8 XAML Metro App 中的基本 UserControl 类

    .net - WPF 翻译转换

    c# - 将 IsMouseOver 绑定(bind)到 UserControl 中的 ViewModel

    c# - 单击时获取 GridView 单元格的字符串值

    c# - 如何使用 C# 在 WPF 中播放 YouTube 视频

    wpf - 有什么方法可以使用鼠标拖动/调整 Canvas 大小?