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?
sender is your control so you could also right this.SetCurrentValue.
public void SetImageON(object sender, MouseEventArgs e)
{
ImageButton btn = (ImageButton)sender;
btn.SetCurrentValue(TagProperty,imageOn.Source);
}
it seems as though you might wan't to just save the source of your image in the control , instead of the entire image.
But if you wan't to use an Image object in code like this
xaml : in your template .
<StackPanel x:Name="myPanel" />
cs : in your control :
myPanel.Children.Add(imageOn);
Give a name to your image, like x:Name="PART_Image"
. Then in your code behind override OnApplyTemplate method and store it into a variable.
private Image PART_Image;
public override void OnApplyTemplate()
{
PART_Image = this.GetTemplatedChild("PART_Image");
}
In this case you can access it in your method like:
this.PART_Image.Visibility = Visibility.Collapsed;
You can achieve what you want with a Trigger:
<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>
That way you don't need the event in the code-behind. If you wanted to, you could make imageOff and imageOn DependencyProperties, that way you could define the source images in xaml too:
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)));
}
}
So when you declare an ImageButton in xaml, you can do something like this:
<local:ImageButton imageOn="/Resource/Path/To/imageOn.png" imageOff="/Resource/Path/To/imageOff.png" />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.