0

I start the WPF today, I'm trying to implement a custom control.

My problem is that I can not select an element in the template.

My code:

[Generic.xaml]

 <Style x:Key="{x:Type local:ImageButton}" TargetType="{x:Type local:ImageButton}"  BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ImageButton}">
                <StackPanel>
                    // -> My image
                    <Image Source="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"></Image>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

[ImageButton.cs]

public class ImageButton : Button
{
    public Image imageOff { get; set; }
    public Image imageOn { get; set; }

    static ImageButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
    }

    public ImageButton()
        : base()
    {
        this.MouseEnter += new MouseEventHandler(SetImageON);
    }

    public void SetImageON(object sender, MouseEventArgs e)
    {
       //Here i wanna change my image from StackPanel
    }
}

Am I on the good way ? How can I change that image?

4

3 回答 3

0

您可以使用触发器实现您想要的:

<Style x:Key="{x:Type local:ImageButton}" TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ImageButton}">
                <StackPanel>
                    <Image Source="{Binding Path=imageOff.Source, RelativeSource={RelativeSource TemplatedParent}}">
                        <Image.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Image.Source" Value="{Binding Path=imageOn.Source, RelativeSource={RelativeSource TemplatedParent}}" />
                            </Trigger>
                        </Image.Triggers>
                    </Image>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这样您就不需要代码隐藏中的事件。如果您愿意,您可以创建 imageOff 和 imageOn DependencyProperties,这样您也可以在 xaml 中定义源图像:

public class ImageButton : Button {
    public static readonly DependencyProperty imageOffProperty = DependencyProperty.Register("imageOff", typeof(Image), typeof(ImageButton), new PropertyMetadata(null));
    public Image imageOff {
        get { return (Image)GetValue(imageOffProperty); }
        set { SetValue(imageOffProperty, value); }
    }

    public static readonly DependencyProperty imageOnProperty = DependencyProperty.Register("imageOn", typeof(Image), typeof(ImageButton), new PropertyMetadata(null));
    public Image imageOn {
        get { return (Image)GetValue(imageOnProperty); }
        set { SetValue(imageOnProperty, value); }
    }

    static ImageButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
    }
}

因此,当您在 xaml 中声明 ImageButton 时,您可以执行以下操作:

<local:ImageButton imageOn="/Resource/Path/To/imageOn.png" imageOff="/Resource/Path/To/imageOff.png" />
于 2013-11-19T11:48:01.363 回答
0

sender 是您的控制,因此您也可以正确 this.SetCurrentValue。

public void SetImageON(object sender, MouseEventArgs e)
{
    ImageButton btn = (ImageButton)sender;
    btn.SetCurrentValue(TagProperty,imageOn.Source);
}

似乎您可能不想只将图像的来源保存在控件中,而不是整个图像。

但是如果你不想在这样的代码中使用 Image 对象

xaml:在您的模板中。

  <StackPanel x:Name="myPanel" />

cs:在你的控制之下:

 myPanel.Children.Add(imageOn);
于 2013-11-18T09:31:37.667 回答
0

为您的图像命名,例如x:Name="PART_Image". 然后在您的代码中覆盖 OnApplyTemplate 方法并将其存储到变量中。

private Image PART_Image;

public override void OnApplyTemplate()
{
  PART_Image = this.GetTemplatedChild("PART_Image");
}

在这种情况下,您可以在您的方法中访问它,例如:

this.PART_Image.Visibility = Visibility.Collapsed;
于 2013-11-18T09:32:32.120 回答