Round Image Custom Control in WPF C#

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys welcome to tactic devs in today's video i'll be showing you guys how to create a round image custom control in wpf so i already have a project set up here without further delay let's get to the coding so in my project i added in an image and i'll be using this image to illustrate the use of this control so i'll go to my project and add in new item so under the wpf tab i'll select custom control and i'll just give it a name round image okay so visual studio went ahead and added in a class called round image that inherits from the control class i'll get rid of this summary here so basically this class is our custom control class and i'm going to declare some properties that are going to hold information associated to this control now i'm going to declare them in form of dependency properties so this is very useful for data binding so by using this code snippet prop dp and pressing tab twice we get this code snippet so i'm going to declare the first property and it will be of the type image source i'll just give it a name image and this is going to store information about the image that we are going to use in this control i'll change its owner class to round image which is basically this class and i'll set its property metadata to no i'll get rid of this comment i'm going to add in another property and this will be of the type double i'll give it a name zoom factor so this property will be used to set the zoom level on the image i'll set its default data to 1. now it's important that whenever you're using elite row that you specify what type if we leave it at one here the compiler will interpret this as an integer now if you look at the two tip there it says int 32 but the property declared here is a double so i need to specify that this one here is actually a double so by adding d at the end the compiler will now know that this is a double i'll get rid of this comment here and i'll declare another dependency property and i'll give the type double as and i'll give this one a name of x translate so this property will be used to align the image along the x axis and i'll give it a default value of zero i also specify here that is a double by adding d i'll create another property for the y-axis okay so i'm going to create the final property which is going to be also of the type double and i'll give it a name border width so this property will be used to set the width of the border because this control is going to have a border around it i'll set its value default i'll set that to zero okay so i declared some dependency properties and i'll just go through we have the first one is of the type image source and the second one is double that's the zoom factor the x and y translate as well as a border with property so every time you add in a custom control visual studio is going to add in a folder called themes and this folder is going to contain a file called generic i'll just go ahead and open up this file so this file is actually a resource dictionary that has a style defined now if we take a closer look at the styles target type you will notice that it targets the round image class and the round image class is the class of the control that was just created now this style here sets the template property and assigns a control template so a control template is what defines the visual appearance of a control so that's the stuff that you see on the screen when the control is rendered now apparently we only have a border defined here so if i go ahead and compile and use this control in an application the only thing that i'm going to see is a border so i'll be redefining this control template so i'll go ahead and get rid of the border and i'll add in an element which is a view box so the view box will help me resize the control in a proportional way so that the aspect ratio is reserved i'll add in an ellipse that's going to provide the round shape now the ellipse has got a property called the stroke property which is basically the line that surrounds the ellipse and i'm going to set the value of the stroke which is the color of that line i'm going to bind it to a value using a template binding and i'll bind it to the border brush property now this class round image inherits from the control class and the control class has got a property called border brush so i'll be binding this strokes value to that property so by using the template binding what i'm simply saying is for this stroke get the value from the border brush property of this class here now it also has another property called stroke thickness so i'll be binding it to the property that i created earlier on which is the border width here now the ellipse has got another property called the fill property so basically the fill property is what defines the color of the ellipse now the fill property takes in a brush wpf has got a class called image brush so in place of a solid color i can actually use an image brush and an image will be rendered in the fill of the ellipse so i'll set that by saying ellipse then fill property and i'll use an image brush for that now this image brush has got a property called image source so image source is what's going to define where the image can be found and that's the image that's going to be rendered in the control so here i'm going to bind it to the image value that i created earlier on here so that's image and it's of the same type which is image source now i can use a template binding but wpf won't allow me to do that and the reason for that is this class inherits from a freezable class so it doesn't allow template bindings now i'm going to use the ordinary binding which is just binding now basically the difference between template binding and binding is just that template binding is more of an optimized version of binding that's suited for control templates so in this case i'll use binding and i'll say relative source and for the relative source i'll go for templated parent and the path to that value will be set to image okay so in this binding expression here what i'm actually saying is get the value from the object that's going to use this as a template the templated parent okay so get the image property and use it to display the image now i want the image inside this ellipse to be able to scale so that's basically zoom in and out and i also wanted to be able to move along the x and y axis so in the case that you want to align that image just to a specific position you can actually do that so i'll do that by setting the relative transform property on this image brush so just go image brush and i'll say relative transform now inside this relative transform i'm going to add in a transform group so what the transform group does is it allows me to set more than one type of a transform so in this case i want zooming as well as panning so i'm going to use the scale transform and the translate transform so here i'm going to define a scale transform now when the image is scaling it's going to use an origin to scale so from that origin i can set the x center and the y center to a specific origin now because i'm using relative transform so it only uses values between zero and one so for me to really go for the center i need to get half of the width and half of the height of the image so i can do that by just using 0.5 which would be half of the height and half of the image of the width so i'll go for center y i'll do the same 0.5 okay now for the scale x i'm going to use a binding as well i can't use a template binding for this because it also inherits from the freezable class so i'll go relative source again i'll use templated parent and i'll set the path to zoom factor so i'll be scaling this image based on the zoom factor so for the scale x i'll use the factor so i'll just go ahead and copy and also be using the same zoom factor for the scale y property because this will be proportional scaling so everything will scale at the same proportion so i also use the same property which is the zoom factor okay now i'm going to add in another transform and this transform will be of the type translate transform so it has a scale it has a transform property so along the x-axis i need to set the x value here and using a binding again say relative source templated parent i'll specify the path by saying use the x translate property i'll just go ahead and copy this so i'll do the same for the y property and i'll set the path to y translate okay so we have an image brush and i've said some relative translates here and that's a scale and translate transforms now this image has got a property called stretch it's important to also assign this property or assign that to uniform so as we scale the property the image should also scale in a uniform way so that's for the height and the width so that should be uniform scaling so i guess this this is it for the control i will also set the height and the width on the ellipse here so i'll give it an initial height of 100 pixels and width of 100 pixels so these initial values are important so that um the viewbox can know when where to start resizing from okay so i'm going to do that and i'll go to the main window because i think that's it for the control here so i'll go to the main window here and i'm going to add in now before i do that i first need to build the solution so i'll go ahead and build the solution okay so the solution was built successfully so i'm going to add in the control in the grid so it's a round image i'll give it a height and width of 100 pixels okay so when i select this control and here in the properties panel at the bottom tab i'll just open up this so you see there's a property called image so i'll set that image to the cells image and that's the image i added to the project okay so now you can see the image appears here now i'm just going to resize this to make it slightly bigger and when i resize you can see it resizes and reserves the aspect ratio and that's because we added in a view box in the template now i'm going to set the border brush i'll set that to a shade of orange and i'll set the border width i'll set that to 5 pixels okay so here you can see now apparently the image is a bit far off so i want to zoom it inwards so i'll use the zoom factor so i'll try to zoom it to by a factor of 1.5 okay maybe let's say 1.8 okay something like that so right away you see that the image is zoomed in but is a bit misaligned so i want to shift it along the y axis and i can do that by using the y translate property so now because in the control i used a relative transform which means i use values between 0 and 1. now apparently right now there's a zoom factor on this image so the values are kind of offset however if because it's still a relative transform so the transformations have to be made in small increments unless i used a transform which is different from a relative transform that way i can use absolute values like pixels let's say i wanted to move this image downwards by 50 pixels i could just type in 50 pixels that's if i chose to use the transform now here i'll try 0.2 and that's not enough maybe 0.3 okay let's go for 0.4 okay something like that okay so we have the control here round it has a border and the image is aligned perfectly so go ahead and test the application and see what happens all right so right now the application is up and running and you can see the round image control displays perfectly so that's it for today's video and remember to like and subscribe to this channel and i'll see you in the next one
Info
Channel: Tactic Devs
Views: 264
Rating: undefined out of 5
Keywords: Wpf, custom control, modern ui design, .net5, beginners, visual studio, gui
Id: 5r_XcdWRQ6Y
Channel Id: undefined
Length: 19min 32sec (1172 seconds)
Published: Sun Sep 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.