C# WPF UI Tutorials: 29 - Sending a Chat Message

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] so I thought what I do in this video is do the actual sending of a message at least on the client side to simulate what it would do when you actively send a message so right now we've now got these chat messages loading but what if you receive a new message or you send one right you - you know you send right now we just have a pop up so why not actually add the message to this view so that's what we're going to do in this video is get this you know adding in there one small thing I did notice though with about to do this video is this dialog popped up in the center of the screen so if your views say over here it kind of looks funny when it's you know it's not centered and so let's first Center this you know this chat message has basically the pop-up dialog sort of being sent for the screen in the center of the owner so that's a nice quick quick drink to make so it's open the base dialogue user control go to the show method and then before we show it basically state show in the center of the parent so M dialog window doc windows started location equals owner and that should fix that little annoyance let's just double check or not so that doesn't have an owner so that will be the other issue from dialog dot owner equals men do have access to the main window anywhere so I'm going to do application dot current dot main window and now it should show in the center of that window hopefully there we go so now wherever the you know the users attention is regardless of you know the center of the screen when they click they get this nice centered dialogue that's that other way so first thing we want to do then is change when we type in here and press end where to send a message before that will go into the chat West view model and what it is Karen so chat message let's cue list model so on and in the send command here now instead of doing this you want to get rid of this and we basically wanna send an actual message so items dot add new message they send a new message so again once we do the server code this will actually send the request off to the server and then once it's verify that it's sent it'll change from like a you know a loading state of will ascending state into an actual sent message but for now this is this is good enough to link up all the UI so we want first-run initials whether to make a message up here message equals now you know I don't haven't even added a actual message here we didn't select add public string hemming message text message text call old England or the text for the chromatic being written so in that case we mustn't have anything bound in the chat page so box now we don't so in that case now text or refine into the pending message text for the updates or things up there property change so that it updates whenever you're talking and we also have ethanol out be it for now so message is pending message text message sent time is and again this will be updated once we have the real server to be the actual unit on it was really sent but for now we'll just put the current time profile picture ID we actually doesn't matter because we're sending the message so send by me because true as send the name and that will do now I'll see first of that works so clicks and a null reference exception okay so items is null in this case because we haven't already denny items so we can create again for now we'll just say if items because North articles new lest and we'll start to think about thread safety in another video so if you click send twice or regardless of that at multiple places are trying to you know add items you really want to lock this list but we will do that in a completely separate video so this is not technically threads you've put good enough for this video okay so what Alan I'm guessing but we're not seen so the items are in there oh and I know why so you can see this this list is not dating yet when we do you know we set the view model itself the update so with view models so far we've done the body weaver and the property changed so that when you know a property change is like items when the whole items change or when this changes or this changes effectively body weaver in the background fires this property changed event for us so it calls the on property change name of the property and that's how the the current view model binding works that's pretty much all there is to to binding as I mentioned before this notify property changed now that isn't strictly true because there's one of the real instance of view models and that's for collections and collections have I believe ID collection changed events of something along those lines it's called so what we want to do is change this list because when the items inside the let's change view models have a specific way of monitoring that and that's through this collection changed event so we want to change your list to an observable with which is in observable not observable a suburb of collection and that is in the system collections object model now we go into this you'll see this I notified collection chain that's what I was thinking of so this is the the other interface there's your standard when you know the whole thing changes but when just items inside of a collection change and you want to update a list this is the interface that gets implemented and then all it does is raise that collection changed instead of that property changed and then controls like the rock and find it in the chat message rest control so things like this items control in WPF automatically listen out for when you buy and item source it first checks of this implements the notify collection changed and if it does then it will effectively fire whenever that collection has changed and update the UI so all we have to do is change the list to an observable collection for this you know event to fire so now we just need to fix everywhere else where we've got the new list change that to new observable collection there's a few more places there we go so all of them there has changed the property from our list to an observable collection then compiled the application with ctrl shift B and simply family errors and double clicked on them and then you know changed everywhere we've got the list into an observable collection so now we send we should hopefully see one there we go so now we can add messages sounds a good start that's quite a few things you need to do here now to make this much nicer experience so the first thing is we want this message to slide up like you know fade and slide off we don't want to just appear in have the whole applications got nice animations and things slide in and out and load in and out and then we know how this nasty just don't straight in with no animation so let's animate this you know each new chat message in so we'll start with making a new [Music] animation so we go to framework animations the framework elements animations the fade in and out we probably want the slide in and out we have an existing one I've been called animate slide in from bottom and that was in when I was a looking and couldn't find it was a cell house in the wrong class this is in the framework element animation attached properties file that's in the attached properties this one here that's what I was looking for and we already have the ones for you know animating sliding them from the left the bottom the top the right now we don't want a property for sliding in and out we just want it for sliding in and we also only want it to happen when it's a new item so we'll simply copy this existing slide in from bottom and we'll do sliding from bottom and [Music] animate sign in from bottom unload we'll call it copy and paste that into there and it makes a framework sliding from the bottom unload and we will have basically just don't want it to animate it it's not unload every value is true so all we do for that is we always animate them in essence but if the values false then we don't want to animate in at all so the first load which has the effect of you knows bypassing the animation if it's the first load that can be passed in as the value this time because we it's the same thing if it's true then or rather than not value so if we don't want to animate in then we effectively tell it we are first load without of you know bypass that and we use that rule assuming them for the animation time typically if its first load we don't have any animation otherwise we do in this case if the values true we want to animate in if it's false then we simply skip so all we've done is now repurpose the value so if we set this you know slide in from bottom to false it'll act as if it's the first load and it won't animate so therefore it will effectively be a blank tab you just simply won't animate otherwise we set it to true it will animate and it will animate at this you know given time so that's all we're doing there we can now place this animate slide in from bottom on load into the I think the chat list the chat message let's control we want that in the samel and we want to on this actual each individual item so we'll paste that in the local value equals and then to check this works I'll just set it to true first and we're on and we should get a an animating them from the bottom for all items now which does work just so you can just about see that the the animate you know the stretching but they're also fading what you can just about tell the or animate up so now we simply want to limit this to only when new items get added so let's do a binding we'll call this new item and now we need to add this new item so we first need two others one other thing I know I need to do now due to this animation somewhere we check on first load where do we check we check for a visibility somewhere first load and we make it so that I think it's framework on and tell them I thought it was in this one and it's always in the base lion fade [Music] add fade begin visibility where is it there we go it's in the after keep going to the wrong part it's in the framework elements animation such properties again in the base attached property while the animation base property and then on the first load so this was this is handling you know when the UI is first created if it starts off hidden or in this case yeah if it starts up hidden and we'd make it hidden the way we've now gone the animation is we want certain properties like this one to be hidden anyway and then animate in because this is not necessarily going to be first load or actually we can fix this without changing that so I know it stands as the value so when the value changes to true on first load which is ORS animating or fading in it's not going to be hidden so that's the issue that we we want to effectively immediately on add animate this new message in but it needs to start off hidden even though the animation is technically true because we've you know repurpose the animation so it basically does need to remove this check in start off hidden before we decide to animate and that's just disregarding any check I don't think that'll cause any other issues we'll we'll double-check with the animations but I know we need to always hide otherwise we'll get a bit of a glitchy looking UI so that's that there we were doing the new item okay so now in the chat message list item view model we will now need a new properties boolean called new item by indicating FS Artemis at is the first main list of items was created use as a flag for and a making em so by default this will be false which is fine then in our view model where we send a message which is in the chat message list view model here we now simply flag the new item here so now that animation should only happen when we add new items because we've told the animation to only run based on that button so now we load these you can see the fade in now is normal and then if we target a new message it animates in so there's that you can add loads of messages so it seems to be working ok and if you scroll then it doesn't we scroll which is fine we don't want to be intrusive oh that's ok so once you've scrolled looks like once you've come out and then scrolled once the message isn't scrolling to the bottom so it kind of start there and then fails so we're gonna have to fix that yeah um [Music] right I think then what we'll do this is obviously scrolling to the scroll viewer complaining about is needs closing and rebuilding again I'll ignore that for the minute so the chat message list control how is a scroll view and that's things growing so I think we need another attack property similar to this so I've got a scroll to bottom onload just fine and so we've got scroll to bottom onload once we name this class to scroll viewer Pat Rothfuss because now we're going to more than one open/close that copy this one so it's going to be very similar taste again and we'll call this one also scroll to bottom property and this well automatically keep the scroll at the bottom of the screen when we are already close to the bottom then on value changed his design fine scroll you'll find data contact now it's going to be scrolled changed instead and this can be controlled scroll changed this will now be a scroll change event dogs should be happy with that if we rename the function as well now we're hooking into when the scroll changes this time we want to I guess what we don't need to check is a scroll view because we've done it there so for scroll equals planned a scroll viewer now we want to first check if we are close enough to the bottom so that will be if scrolled up the scroll or height to the maximum available scroll height minus the current position it is vertical offset I think it is so if the difference between the belly bottom and where we currently eyes say less than 20 so if we're practically at the bottom of the scroll already then in that case we want to scroll to end and I think the difference between scroll to end and scroll to bottom is let's scroll to end every turns I think straight away compared to scroll to bottom which I think I'm not sure the two differences but let's try scroll to end of that some work will do scroll to bottom so now all we should have to do is attach this property to here as well and now every time we're close enough to the bottom and the scroll position changes it will stay at the bottom so it shouldn't affect our normal scroll which is fine it doesn't affect our well it affects the dragging in the sense that now you can see here what's the bottom of the scroll bar I'm flicking now and as I drag or it doesn't scroll until a break past our difference of 20 so now I can scroll you know up to that variance of how close you are to the bottom before it moves is is your value of 20 so we can adjust that to whatever value we like so we can change that to say 10 and it just means that if the user is only very marginally off the bottom and you know they're going to miss that so we go to there and now drug because he starts 10 which is that much so they're going to be right near the bottom so I think 20 is probably a good number so we can see that that's working because basically it's not allowing us to it well rather is keeping the scroll bar at the end whenever were close to the end and then when we now send the message hopefully that then keeps that fixed that little scroll issue if we're away from the top when we send then it won't scroll down because you don't want to pull the user away from whether we're looking at the message but the new message does appear at the bottom so right I've just numbers scroll up then scroll back down they are there but it doesn't jump down whereas we're already at the bottom and we type then it's you know it Scrolls in and it's you know a nice effect so that's that and on I think in future again once we say up the top any new message comes in will pull or banner here that says you know unread messages or something and then as we're scrolling through we can make sure that as the messages come into visibility of the unread they get marked as read that sort of thing but for now we won't do that in this video let's carry on cleaning up a few more things so one thing when we send a message we want to clear the message text because we've now sent the message so [Music] so I can find where I was again in chat message list view model after we've something message for your attending message text let's one will clear that off so now we have a message send and it clears the message now the other thing is once we send I'd expect that to be focused again and also when we change page I want it to be focused let's just add some focusing to this page so we go to chat age and we go to actor let me just clear this off I mean just do the whole deleting of open project folder delete the bin the object folder I'll also delete the vs folder and then I'll restart visual studio and that should fix this issue so I'm just going to restart visual studio for a moment okay so restart visual studio after deleting those folders and we've got the UI buck so let's carry on where we were and we wanted to on the send button so we've got a command send but this is purely built into this UI we want when we click this button to focus this text box so first thing we want to do is name this text box don't actually reference it in code-behind so name is going to be message text then on the send button we will have on the click event which i think is okay um [Music] yeah because they're basically when you're collecting is when you're losing focus that the only real time you want to refocus that boxes if you've clicked that button so on the click event we go to the code-behind now rename that send button clicked and that was with control and pressing R twice oh hold ctrl + R twice and then you can rename the function and it will also rename the sample for you add a description and the send button is clicked maintain focus on the text box I think we could probably also simply just say somebody with focus above this false let's first try that actually see that solves the issue we might not need to do this function because if it's not focusable I think that's just focusable in terms of visual not in terms of keyboard focus though let's try it so by clicking here come on visual studio and it's going to hang there we go go by traveling here now and click this button so it'll actually solve that issue so all of that to do there is simply set the send button visibility not visibility the send button focus beaultiful so we can get rid of this clucky lamp i was going to simply say on this click event then do message text focus glad that but obviously simply preventing the send button on beam focusable saves that in requirement anyway that's kind of a shorter way of doing it now the other thing we want is we want this to be focused when we first load so we've already got the helper for that that's the local is focus profiteer believe so now by default when the page is loaded I guess we should have it focused so they'll get starts focused which is what we want when we change pages it's dim focus but if we've lost focus say click in here and then we change really whenever you're going to a new chap regardless of whether focuses which is now like say last you also want to keep it focused then so to do that we'll go to the chat pages view model changed and once we're failing in make the message box focused so then we'll do the message text art focus so then in all instances the message box is staying focused which is the main thing we want so now we do that we've got focus we click away you know lose focus from there but we then change we're back to being able to type straight away the one decision I made of initially was if you're typing we do this and then you click send I kind of want to do the opposite now I want to interact any way I expected for sentiment send the message if I want to then actually have an enter in most applications you typically hold the ctrl key and press Enter to get you your actual enter that seems to be the default behavior so we're going to flip this around and do that so by default we want to enter to send the message but if we do want a newline want to hold ctrl and press Enter so let's do that we'll do this with I think we I guess we could do it with an attached property maybe yes let's do with an attached property so if we go to attach properties text attached properties its focused focused property focus and select and we want now this one will be why shall we call this control and new line property because by default what we're going to do is we're going to remove this except return so it doesn't except return by default and then we're going to inject the the enter if we've got control house which you know simulate the except return but then by default pressing enter will actually cause the [Music] pressing enter will do nothing on the text box so will also then fire a laser point when we press ENTER we then want to fire a command so how could we surpass that command into an attached property we can't okay now let's not do an attached property in this case because we want a little bit more customization and what we're doing so we will just have in that case then instead we'll do a preview key down yeah preview key down new event for this so every time we're about to press a key but before it gets actually injected if you will we want to do something so we've removed except return so no longer can you press ENTER to add a new line so if we quickly show you that now when we press ENTER we don't get a new line but you still send the message so that's hard for the job when I want Matt to do that but on enter we want to send the message so go to the code-behind and give you the input into the message box and this fund as required so in this message box we first want to get the text box itself so that will be the sender as a text box then we want to check if the key that's presses enter so if the event T equals key dot enter then we want to say that we've handled it so that the text box and do anything else with it then we want to say the view model dot send so we'll send the message so now we should have the send message whenever we press enter in the text box which we do is then clear the text and we can type a new message that's a lot more standard and how we expect we might not need to do this and to send though if we have this probably just wants to be is default so it's default to true then let's just remove this send for impacts comment this whole thing out for a moment and let's see if that has the same effect where we don't need to manually send and we simply have a you know a working enter but at least you've seen how we would do it manually so yeah so now let's send being the default action sends anyway so the one thing left to do is if we hold ctrl key and press Enter we then want to add a new line to this textbox so in this case we've got if the key is enter and now we need to check the control key is press which is the left or right control we don't mind so for that we do keyboard dark modifiers and modifiers are your you know you control your alt your shift keys think there's one other and then that is simply an enum so we go to that it's modifier keys which is an enum and then you've got yet alt ctrl shift over the windows key obviously so I've just done a video on enums if you want to know about flags and what we're doing here book effectively we just want to check on the modifier key controllers pressed so for that we can do house flag and that would be key dot not ki modifier key dot control so this will now check if we've got enter we press enter at the same time as having control pressed now we want to add the new line so we don't need to send a message now we want to add a new line at the point where the cursor is so to do that we first need to get the index which is textbox dot correct index then we want to insert a new line so that will be flexbox text equals text box text dot Panzers we want to start at the current correct position so we insert the value where we are an environment new line and then finally once you've inserted the new line we want to make sure they're the correct that you know this thing here flashing now what's the correct so when we first it index it's basically saying if this was the text box now and it's got these three eye then the correct index would be three there would be two we could be zero zeros here ones here tuesdaya oh yeah so I three would be here so we'll be at position three then we're going to insert a new line after that three so effectively like that but now this correct position is four so we then want to make sure or rather the manner before depends how long the string gets when you line and a new line is typically it return carriage a new line so it could be two characters so what we want to do is now shift the career forward to the new line so we do text box darker up index and you just do you find applause equals you've got to make sure we stay because it might have changed with inserting that so we want to base it off the original index its index plus and then the environment like new line length so however many you know positions forward that was so we now run this holding ctrl and pressing enter should now preventively just insert a new line wherever we are also we send the message normally now I hold ctrl and press ENTER we get the new line so I go to say middle and hold ctrl + Enter it keeps you know it does what X we're expected to do which is insert and enter at where we are can kind of keep the you know this correct at the right position so now we can send the message nice and quick or you can type a you know where a new line by holding ctrl and pressing enter and there we have it so now we have a much nicer way to send messages nice and fast the animating nicely so you can go to an existing one you know an animator message again and I'm sure we can simply copy and paste text as well now this is the the only downside here actually with accept return being false when we copy and paste new lines it gets removed so let's just fix that then so in that case we want to and this is where we might have to do what we did original so I do accept return here will now get the new line by default and also the send button won't capture that enter so we're gonna have to flip this logic a little bit now so now we do this member we just get a new line so it's kind of killed that so let's go back to our code so then in this case if we are and to keep Liam pressed and we get into here then we simply want to say if your event pressed if we have control pressed then we do what we originally did which is to insert the new line which might work without it but I don't think it will cause holding control prevents and enter being pressed anyway so we'll leave that in otherwise they have simply pressed enter so we want to do what we did before which was simply to call the view model sentient effectively have the same job as a send button and then finally either way we want to make sure it's been handled because we're now manually handling the message mark the key as handled so we're we're effectively completely replacing the Enter key function both allowing us to now by default I guess paste multi-line text end so let's see if this networks so we tart away enter now sends we hold control we get the newline that still works now if we paste we still don't get newline Oh that's not a new line copy that paste there we go so now we can paste in new lines that seems to be working nicely so I think that's it for this video I think we've covered quite a bit there we've now got the ability to you know click into a message and you know send a message paste text in do new lines and it's nice and quick it you know it's fast and we've kept the animation so hopefully this video was again enjoyable and we've done something quite nice there any comments feedback just let me know and again I hope it was useful [Music]
Info
Channel: AngelSix
Views: 16,712
Rating: undefined out of 5
Keywords: wpf, send, chat message, chat app, chat, network, real-world, cross-control, syncing, navigate, navigating, page, change, advanced, settings page, text edit, edit text, textbox, control, settings, sli
Id: 2FUhd3GsAaY
Channel Id: undefined
Length: 43min 51sec (2631 seconds)
Published: Thu Aug 17 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.