2

2 番目のソースを追加して Image クラスを拡張したいと思います。XAML で 2 番目のソース (元のソースと同様) を定義し、マウスがこの画像に出入りするときにこれらの画像を変更したいと考えています。

私は自分で試しました:

class MainMenuImageButton : Image
    {
        public static readonly DependencyProperty Source2Property;
        public ImageSource Source2 
        {
            get { return Source2; }
            set
            {
                this.MouseEnter+=new System.Windows.Input.MouseEventHandler(MainMenuImageButton_MouseEnter);
            }
        }
        public void MainMenuImageButton_MouseEnter(object sender, MouseEventArgs e)
        {
            this.Source = Source2;
        }
    }

しかし、それは機能せず、完全に間違っていると思います。誰か助けてくれませんか?

[アップデート]

私はこれを書きました:

class MainMenuImageButton : Image
{
    protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
    {
        var source = (BitmapSource)Source;
        var x = (int)(hitTestParameters.HitPoint.X / ActualWidth * source.PixelWidth);
        var y = (int)(hitTestParameters.HitPoint.Y / ActualHeight * source.PixelHeight);
        var pixels = new byte[4];
        source.CopyPixels(new Int32Rect(x, y, 1, 1), pixels, 4, 0);
        if (pixels[3] < 10) return null;
        return new PointHitTestResult(this, hitTestParameters.HitPoint);
    }
    public ImageSource Source1
    {
        get { return GetValue(ImageSourceProperty) as ImageSource; }
        set { base.SetValue(ImageSourceProperty, value); }
    }
    public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("Source1", typeof(ImageSource), typeof(MainMenuImageButton));
    public ImageSource Source2
    {
        get { return GetValue(ImageSource2Property) as ImageSource; }
        set { base.SetValue(ImageSource2Property, value); }
    }
    public static readonly DependencyProperty ImageSource2Property = DependencyProperty.Register("Source2", typeof(ImageSource), typeof(MainMenuImageButton));
    public MainMenuImageButton() : base() 
    {
        this.MouseEnter += new MouseEventHandler(MainMenuImageButton_MouseEnter);
        this.MouseLeave += new MouseEventHandler(MainMenuImageButton_MouseLeave);
    }

    void MainMenuImageButton_MouseLeave(object sender, MouseEventArgs e)
    {
        this.Source = this.Source1;
    }

    void MainMenuImageButton_MouseEnter(object sender, MouseEventArgs e)
    {
        this.Source = this.Source2;
    }
}

ただし、機能することもあれば、例外が発生することもあります。

追加情報: 値が想定範囲外です。」


理解できたかどうかわかりませんが、次のことを試しました。

class MainMenuImageButton : Image
{
    public static readonly DependencyProperty Source2Property = DependencyProperty.Register("Source2", typeof(ImageSource), typeof(MainMenuImageButton), new PropertyMetadata(true));
    public ImageSource Source2 
    {
        get { return (ImageSource)GetValue(Source2Property); }
        set
        {
            BitmapImage logo = new BitmapImage(new Uri(value.ToString(), UriKind.Relative));
            SetValue(Source2Property, logo); 
            this.MouseEnter+=new System.Windows.Input.MouseEventHandler(MainMenuImageButton_MouseEnter);
        }
    }
    public void MainMenuImageButton_MouseEnter(object sender, MouseEventArgs e)
    {
        this.Source = Source2;
    }
}

それでも何もありません。私は何を間違っていますか?

4

4 に答える 4

4

MSDN のカスタム依存関係プロパティの記事を参照してください。イベント フックアップは、依存関係プロパティのPropertyChangedCallback.

イベント処理の代わりにトリガーを使用することもお勧めします。ただし、これは、使用するすべての場所で XAML を複製する必要があるという意味ではありません。既定のスタイルでイメージ切り替えトリガーを使用してカスタム コントロールを定義できます (「コントロール オーサリングの概要」の「テーマ レベルでのリソースの定義」を参照してください)。"Source" および " Source2 " 依存関係プロパティを持つMouseOverImageControl、次の既定のスタイルを定義できます。

<Style TargetType="local:MouseOverImage">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MouseOverImage">
                <Grid>
                    <Image Name="SourceImage" Source="{TemplateBinding Source}" />
                    <Image Name="Source2Image" Source="{TemplateBinding Source2}" Visibility="Hidden" />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="SourceImage" Property="Visibility" Value="Hidden" />
                        <Setter TargetName="Source2Image" Property="Visibility" Value="Visible" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

イベント ハンドラーを使用する場合は、Source の元の値を保存し、それを元に戻すハンドラーを追加し、ユーザーがいつでもorをMouseLeave再割り当てする場合を考慮する必要があります。2 つの別個の "Source" および "Source2" バインディングを備えたトリガー ソリューションを使用すると、これらすべてが自動的に処理されます。SourceSource2

編集

ただし、機能することもあれば、例外が発生することもあります。

追加情報: 値が想定範囲外です。」

私の推測ではHitTestCore、ソースが変更された後、レイアウトに適用される前に発火しているため、 と の間に不一致がActualWidthありsource.PixelWidthます。これらを計算に含める理由がよくわかりません (常に同じであるべきではありませんか?) 以下を使用してみてください:

var x = (int)hitTestParameters.HitPoint.X;
var y = (int)hitTestParameters.HitPoint.Y; 
于 2013-08-19T15:15:22.440 に答える
4

イメージの拡張はやり過ぎです。トリガーを使用してソースを交換するスタイルを定義するだけです。

<Image>
  <Image.Style>
    <Style TargetType="{x:Type Image}">
      <Setter Property="Source" Value="Image1"/>
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="Source" Value="Image2"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </Image.Style>
</Image>
于 2013-08-19T14:36:43.377 に答える