【问题标题】:WPF Custom Control - Button EventWPF 自定义控件 - 按钮事件
【发布时间】:2013-11-18 09:28:07
【问题描述】:

我今天启动 WPF,我正在尝试实现自定义控件。

我的问题是我无法在模板中选择元素。

我的代码:

[通用.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
    }
}

我走上正轨了吗?如何更改该图像?

【问题讨论】:

    标签: c# wpf generic.xaml


    【解决方案1】:

    为您的图片命名,例如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;
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-20
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多