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

发布于 2024-10-12 15:14:33 字数 7402 浏览 3 评论 0原文

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

        <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>

我有两个问题:

  1. 我不知道如何访问控件模板中的图像源
  2. 另外,如果我尝试在图像控件上创建样式并设置属性 Template -> >图像控件没有属性模板。

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

编辑:

我创建了简单的控件,按照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));

    }

我尝试在视图中使用这个控件:

<Grid Background="#99CCFF"  Margin="4,4,4,4">
      <Controls:AvatarImageControl ImageSource="{Binding Path=Oponent.Info.ProfilePhoto,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
</Grid>

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

我做什么坏事了?

我也在用户控件中尝试了这个:

<Grid>
    <Image x:Name="SmallImage"
        Source="{Binding Path=ImageSource, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
        Stretch="Fill"/>
</Grid>

结果是相同的。

我在视图中使用用户控件,我从 Uri 的视图模型类型绑定到 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}">

将绑定模式设置为oneway。

效果很好。

感谢格拉兹科夫先生的帮助。

I would like show pop up when is mouse over the image control. So I create control template, it look like this:

        <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>

I have two problems:

  1. I don’t how can I acces to image source in control template
  2. Also If I try make a style on Image control and set property Template -> Image control don’t have a property template.

My aim is show pop pop window with same image only bigger.

EDIT:

I create simple control, as advice Mr. Glazkov, which have image control, here is it:

<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>

Code behind is the same:

  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));

    }

I try use this contol in view:

<Grid Background="#99CCFF"  Margin="4,4,4,4">
      <Controls:AvatarImageControl ImageSource="{Binding Path=Oponent.Info.ProfilePhoto,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
</Grid>

I bind property type of Uri to ImageSource of AvatarImageControl.

What I do bad?

Also I try this in user control:

<Grid>
    <Image x:Name="SmallImage"
        Source="{Binding Path=ImageSource, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
        Stretch="Fill"/>
</Grid>

Result is same.

I use user control in view, I bind on ImageSource property property from view model type of Uri. Nothing else.

EDIT 2:
Code of Mr. Glazkov produce exception:

{"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

Solution is :

 <Popup IsOpen="{Binding ElementName=SmallImage, Path=IsMouseOver, Mode=OneWay}">

Set binding mode on oneway.

It works good.

Thank Mr. Glazkov for help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无敌元气妹 2024-10-19 15:14:33

您无法为图像控件定义控件模板,因为它不是从 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));
}

You cannot define a control template for the image control because it is not derived from Control, thus it doesn't have a control template. It just renders itself in the OnRender method.

What you can do is to create a User Control with one dependency property ImageSource. Here is the XAML of this control:

<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>

And here is the code behind (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));
}
云归处 2024-10-19 15:14:33

一般方法:

    <CONTROL>
        <Grid>
            <!-- Actual control content -->
            <Popup IsOpen="{Binding RelativeSource={RelativeSource AncestorType=CONTROL}, Path=IsMouseOver, Mode=OneWay}">
                <!-- Popup content -->
            </Popup>
        </Grid>
    </CONTROL>

您也可以通过RelativeSource 绑定访问图像源,只需搜索祖先类型Image。

编辑:现在你的问题已经解决了一点,我可以尝试为你的两个特定问题找到一些代码..
编辑2:太慢了...

A general approach to this:

    <CONTROL>
        <Grid>
            <!-- Actual control content -->
            <Popup IsOpen="{Binding RelativeSource={RelativeSource AncestorType=CONTROL}, Path=IsMouseOver, Mode=OneWay}">
                <!-- Popup content -->
            </Popup>
        </Grid>
    </CONTROL>

You can access the image source via RelativeSource-binding as well, you just search for the ancestor type Image.

Edit: Now that your question is cleaned up a bit i can try to find some code for your two specific problems..
Edit2: Too slow...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文