2

I want to extend System.Windows.Controls.Image with some methods and variables. But as far as I know, WPF controls inheritance considered as a bad practice.

So, is creating a UserControl the only way? I really want to avoid this, because it makes element usage more complicated (for example, you have to call UserControl.Image.Source instead of Image.Source).

Are there any options?

JustLogin
  • 1,822
  • 5
  • 28
  • 50
  • 1
    You can expose a dependency property called `Source` that when fiddled with, touches your _inner_ `Image.Source` –  Sep 06 '16 at 11:39
  • 1
    Can you be more specific about what methods and variables you want? *"WPF controls inheritance considered as a bad practice"* - not true at all, truth is - WPF is simply flexible enough, you will rarely need to subsclass anything. – Sinatr Sep 06 '16 at 11:41
  • @MickyD Yes, I know. But using a whole UserControl brings a lot of unnecessary stuff, when I just need some extra methods in Image class. – JustLogin Sep 06 '16 at 11:41
  • @Sinatr I've read it here: http://stackoverflow.com/questions/1226281/wpf-control-inheritance – JustLogin Sep 06 '16 at 11:48
  • @JustLogin, there are no word "practice" on that page. What I mean is what sometimes you must create custom control, because doing it WPF-way (using control template, attached properties, xaml-extensions, etc.) is simply not enough. But the choice depends. And we don't know what choice should be made in your case unless you supply some details. Why it should be the `Image`? Why not `FrameworkElement` as base class? What this control will be used for? – Sinatr Sep 06 '16 at 11:53
  • @Sinatr It's all about photos in presentations for touch screen devices. So, I want to keep specific animations methods and touch handlers in my class. – JustLogin Sep 06 '16 at 12:12
  • 1
    I've had NO problem on subclassing from WPF controls including form, label, textbox, combobox, etc. Then just use my sub-classed control on the forms. All the events and methods work as planned. Anything improved on the base class for upgrades come along for the ride too. – DRapp Sep 06 '16 at 12:19
  • 1
    _"But using a whole UserControl brings a lot of unnecessary stuff"_ - nonsense. One `FrameworkElement` object is arguably just as slow as another `FrameworkElement` object since they both have layout mechanics. That's what matters, no what extra matters one class has –  Sep 06 '16 at 12:45
  • @MickyD thanks, didn't know this. – JustLogin Sep 06 '16 at 12:49
  • 2
    You've already answered your own question in your first sentence: *"I want to extend System.Windows.Controls.Image with some methods and variables"*. Extend the control, that's exactly one of the things that OO is all about, WPF is no different. – slugster Sep 06 '16 at 13:33

2 Answers2

1

What about Extension Methods in a static class?

For Example:

public static class ExtensionMethods
{
    public static bool MyExtendedMethod(this System.Windows.Controls.Image source)
    {
        // do something
        return true;
    }
}
Andrea
  • 112
  • 1
  • 13
  • 1
    It's a possible way, but I prefer to keep specific methods (like specific animations, which are used *only* in one class) directly in class. – JustLogin Sep 06 '16 at 12:10
  • @JustLogin I'm not very expert on WPF. IMMO, make your CustomImage class and inherit from System.Windows.Controls.Image .. ;) – Andrea Sep 06 '16 at 12:25
0

How about using attached properties and the associated PropertyChangedCallback methods to implement the functionality you desire. For example:

public class ImageProperties
{
    public static readonly DependencyProperty ByteEncodedStringProperty = DependencyProperty.RegisterAttached("ByteEncodedString", typeof(string), typeof(ImageProperties), new PropertyMetadata(null, ByteEncodedStringPropertyChanged));

    private static void ByteEncodedStringPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        Image image = sender as Image;

        if (image != null)
        {
            ImageSource imageSource = DecodeByteEncodedStringImage(args.NewValue);

            image.Source = imageSource;
        }
    }

    public static string GetByteEncodedString(DependencyObject obj)
    {
        return (string)obj.GetValue(ByteEncodedStringProperty);
    }

    public static void SetByteEncodedString(DependencyObject obj, string value)
    {
        obj.SetValue(ByteEncodedStringProperty, value);
    }
}
ibebbs
  • 1,963
  • 2
  • 13
  • 20
  • 1
    Is it possible to add methods via this concept? For example, I want to have FadeOut public function in my class, which makes Image to play a specific animation. – JustLogin Sep 06 '16 at 12:05