0

Can someone help me with my problem:

I want to pass a value to a class that contains a User control using Dependency Property.

I have created a program that Draws Pan And Zoom in an image.

My Pan and Zoom are based from Pan & Zoom Image

During the almost three years in the Office. I created 4 program similar to this one.

So i want it to be reusable instead of copying the code again.

I created a c# class library that contains the Pan and zoom

The class name for the pan and zoom is ZoomBorder and i added a dependency property which is used to check if Pan or Drawing is going to be executed

public bool IsDrawing
        {
            get { return (bool)GetValue(IsDrawingProperty); }
            set { SetValue(IsDrawingProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsDrawing.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsDrawingProperty =
            DependencyProperty.Register("IsDrawing", typeof(bool), typeof(ZoomBorder), 
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null));

Then in that Class library i added Wpf User control and named it Viewer

And i also added Image control in the said user control

Here is the xaml code inside the class library

DataContext="{Binding RelativeSource={RelativeSource Self}}"



<e:ZoomBorder x:Name="viewer" IsDrawing="{Binding IsDrawing}" >
            <Grid>
                <Image Source="{Binding ImageSource}" />
</Grid>
        </e:ZoomBorder>

And below is the code behind of Viewer

public partial class Viewer : UserControl
    {
        public Viewer()
        {
            InitializeComponent();
        }


        /// <summary>
        /// This is for setting the image in the Viewer
        /// </summary>
        public string ImageSource
        {
            get { return (string)GetValue(ImageSourceProperty); }
            set { SetValue(ImageSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ImageSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImageSourceProperty =
            DependencyProperty.Register("ImageSource", typeof(string), typeof(Viewer), new PropertyMetadata(null));


        public bool IsDrawing
        {
            get { return (bool)GetValue(IsDrawingProperty); }
            set { SetValue(IsDrawingProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsDrawing.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsDrawingProperty =
            DependencyProperty.Register("IsDrawing", typeof(bool), typeof(Viewer),
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null));
    }

And here is how i implemented the class. But It doesn't show the Image

<DrawPanZoomResizeMove:Viewer IsDrawing="{Binding IsDrawing}" ImageSource="{Binding ImagePath}" />

But when i do this it's working

<DrawPanZoomResizeMove:Viewer IsDrawing="{Binding IsDrawing}" ImageSource="Image.jpg" />

The image is shown.

And in order to check if the Binding works. I added an Image control (Not in the Library, but in the main project). Then load the Image from the binding. And it worked.

This is the error message when i use a binding

System.Windows.Data Error: 40 : BindingExpression path error: 'ImagePath' property not found on 'object' ''Viewer' (Name='')'. BindingExpression:Path=ImagePath; DataItem='Viewer' (Name=''); target element is 'Viewer' (Name=''); target property is 'ImageSource' (type 'String')

Can someone point the error in my codes. I've been trying to solve this for hours now. But i can't still solve the problem

Update:

I changed the binding into

<DrawPanZoomResizeMove:Viewer IsDrawing="{Binding IsDrawing}" ImageSource="{Binding ImageSource}" />

But the problem is still there. The image doesn't load when i use Binding

Update:

I added this in the MainWindow.xaml

<Window.Resources>
        <vm:ViewModel x:Key="vm"/>
    </Window.Resources>

Then i changed the code into

<DrawPanZoomResizeMove:Viewer IsDrawing="{Binding IsDrawing}" ImageSource="{Binding ImageSource, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Source={StaticResource vm}}" />

The Image loaded on design mode.

But when i run the program. The error become blank

and give me error

System.Windows.Data Error: 40 : BindingExpression path error: 'ImageSource' property not found on 'object' ''ViewModel' (HashCode=26148945)'. BindingExpression:Path=ImageSource; DataItem='ViewModel' (HashCode=26148945); target element is 'Viewer' (Name=''); target property is 'ImageSource' (type 'String')

If i understand correctly the error. The Image source is not found in the viewmodel. And which is right because the ViewModel in my CLASS library doesn't have a ImageSource property Because the Dependency Property is in Viewer.xaml. So what is the right way to solve this?

classname13
  • 123
  • 3
  • 13
  • 2
    You are binding to a wrong variable name, it should be `ImageSource="{Binding ImageSource}"` – Dusan Radovanovic Dec 13 '18 at 05:37
  • Thank you for your fast reply. But the problem is still the same. When i use binding. The Image doesn't show – classname13 Dec 13 '18 at 05:48
  • Do you still have the error or it just doesn't show up? – Dusan Radovanovic Dec 13 '18 at 05:51
  • None so far. But the image doesn't load. It's really weird – classname13 Dec 13 '18 at 05:56
  • What is the value of ImageSource property? Is it Image.jpg or something else? – Dusan Radovanovic Dec 13 '18 at 05:57
  • I would try to change the Type of the ImageSource DP from strig to ImageSource. – Klaus Gütter Dec 13 '18 at 05:58
  • @DusanRadovanovic the value of the image source property is the full path of the image. what i did is copied the value then paste it in the xaml. And it worked(No using binding) – classname13 Dec 13 '18 at 06:00
  • @KlausGütter change the string to BitmapImage? But why is it that when i set the full path of the image in xaml. It work. But when using binding. It doesn't? – classname13 Dec 13 '18 at 06:02
  • Do analyze such problems, I always use Snoop. This allows you to see the current values of all DPs and where they come from. – Klaus Gütter Dec 13 '18 at 06:07
  • You will have to give the relative source to the control - ImageSource="{Binding ImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" - specify whatever the type is of your parent window where you're using the UserControl – Raviraj Palvankar Dec 13 '18 at 06:12
  • @RavirajPalvankar the problem is still the same. The image doesn't load – classname13 Dec 13 '18 at 06:20
  • Did you try setting the Mode=TwoWay - ImageSource="{Binding ImageSource, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" I tested this in a simple application that i created and it works. – Raviraj Palvankar Dec 13 '18 at 06:23
  • @RavirajPalvankar Where do i put that code. In the class library? or in the Main project? – classname13 Dec 13 '18 at 06:42
  • Inside the xaml where you are using the Viewer UserControl and the AncestorType should be the type to which your DataContext is bound i.e. the one from where the ImageSource property gets set. – Raviraj Palvankar Dec 13 '18 at 06:44
  • Hello. I updated the question. Kindly help me :) – classname13 Dec 13 '18 at 07:12
  • 1
    Remove `DataContext="{Binding RelativeSource={RelativeSource Self}}"` from the UserControl's XAML. It breaks all DataContext based Bindings. Do not use an explicit Binding Source as workaround. Besides that, when you want to bind the UserControl's ImageSource property to an ImageSource property in a view model, the view model should *of course* expose that property. Otherwise the Binding is pointless. – Clemens Dec 13 '18 at 08:56
  • Thank you @Clemens. Your suggestion worked. But it worked when i re created the program. I don't know why. – classname13 Dec 14 '18 at 08:35

0 Answers0