Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
necrotic
Aug 2, 2005
I owe my brother big time for this!

Supersonic posted:

I'm going to look into this tomorrow night. I had been using a task because my TUI was being blocked during audio playback. I put my play code inside Task.Run() and this stopped the blocking, but also caused the issue of letting me open and play multiple audio files at once.

https://github.com/naudio/NAudio/blob/master/Docs/PlayAudioFileWinForms.md

This approach should also work in a TUI, and seems to have all the niceties you want built in.

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice
Trying to combine code-behind event handlers with WPF data binding is a great way to run into bizarre bugs that make you tear your hair out. It can work, but when it doesn’t, debugging it is awful. Just use a command - they’re pretty straightforward once you write yourself a RelayCommand (I’m phoneposting so just google that and follow one of the examples you find). You can either figure out the binding incantations to pass the clicked button’s data context as a command parameter and save whatever you need that way, or you can model the current section in the view model and have the command go get it itself.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Okay I might as well play with relaying commands tonight as a starter for interaction. I tried to bind to the SelectedItem property in the ListView to an integer property in the code-behind, but it always just came back zero. That was with a click handler, not with a command and in integer property in a separate view model class. I am chalking it up to late night bad luck for now.

epswing
Nov 4, 2003

Soiled Meat

Bruegels Fuckbooks posted:

The way I do it is: :words:

Preach. This is what I would have posted, but you said it better than I would have.

Bruegels Fuckbooks posted:

c) Your viewmodel gets your model classes through a service, which does whatever CRUD operations on wherever the data source is and creates your model classes.

Bonus points if you inject this service via IoC container. Which may not appear to make sense for small applications, but anything of substance will benefit from this pattern.

Bruegels Fuckbooks posted:

If you need to communicate events between multiple models/viewmodels, a common temptation is to have them subscribe to each other. That can work, but if it gets too complicated to deal with, use pub sub or the event aggegator pattern.

When you say "communicate events" and "subscribe to each other" what specifically do you mean? Subscribe to INPC and look for the nameof(MyProp)? Or a different event?

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

epalm posted:

Preach. This is what I would have posted, but you said it better than I would have.

Bonus points if you inject this service via IoC container. Which may not appear to make sense for small applications, but anything of substance will benefit from this pattern.

When you say "communicate events" and "subscribe to each other" what specifically do you mean? Subscribe to INPC and look for the nameof(MyProp)? Or a different event?

So one time, I had to introduce a viewmodel property which depended on the status of several objects in my model.

E.g. Say a checkbox is checked if object1's status is true, object2's status is true, object3's status is true...

I had an advanced settings popup where you could toggle the status individually, but the viewmodel property was supposed to reflect the status of them all combined.

So I had the big brained idea of "Hey, you know, maybe my viewmodel just subscribes to the INotifyPropertyChanged of each of the models and changes the state as they change" (I might not have been getting enough sleep at the time)

I made the PropertyChanged event of the models public, wrote a method in my viewmodel to check the status of the models, and made it so when one of the models would change the property, the viewmodel would trigger an OnStatusChanged and toggle its status dependent on the model.

Don't that. This is stupid because it couples your viewmodel with your model, and for many other reasons.

With pub sub / an event aggregator though, you can just fire events like "order placed" or "status changed", and whatever is listening responds. If you're ever in the situations where you're like "jesus christ, there's all these classes within classes and models and such, how do I get them to talk to each other", that's how you solve that.

epswing
Nov 4, 2003

Soiled Meat

Bruegels Fuckbooks posted:

With pub sub / an event aggregator though, you can just fire events like "order placed" or "status changed", and whatever is listening responds. If you're ever in the situations where you're like "jesus christ, there's all these classes within classes and models and such, how do I get them to talk to each other", that's how you solve that.

Any pubsub or event aggregators you've used that've worked well in WPF apps?

When you say "you can just fire events like "order placed" or "status changed", and whatever is listening responds" to be honest this just sounds like normal events.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

epalm posted:

Any pubsub or event aggregators you've used that've worked well in WPF apps?

When you say "you can just fire events like "order placed" or "status changed", and whatever is listening responds" to be honest this just sounds like normal events.

An event aggregator is pretty simple - I'd recommend this article: http://www.nichesoftware.co.nz/2015/08/16/wpf-event-aggregates.html which actually includes the full source. Microsoft has a similar article here https://social.technet.microsoft.com/wiki/contents/articles/23314.using-the-event-aggregator-pattern-to-communicate-between-view-models.aspx but it doesn't explain the problem as well.

Some WPF UI frameworks like prism will include an event aggregator in the framework, and you can use that if it's present.

LongSack
Jan 17, 2003

epalm posted:

Bonus points if you inject this service via IoC container. Which may not appear to make sense for small applications, but anything of substance will benefit from this pattern.

How do you all implement DI in a WPF project? I find myself using the locator pattern, where there is a Locator class which has a ServiceProvider, registers all the services needed, and exposed properties like
C# code:
public Foo Foo => _provider.GetRequiredService<Foo>();
The Locator service installs a reference to itself in Application.Current.Resources and is accessed by a static method in a Tools class like
C# code:
public static Locator Locator => 
    Application.Current.Resources[”Locator”] as Locator ?? New Locator();
It works, but I’ve read that some people consider the locator to be an anti-pattern, so I’m wondering if there’s a better way.

SirViver
Oct 22, 2008
The locator pattern is an anti-pattern because it's essentially a static god object that gets you everything everywhere and in doing so hides each and every dependency of a class behind a runtime error.

Just imagine trying to instantiate a class that uses the locator pattern when starting from a blank slate (i.e. no services registered with the locator at all). With classic constructor injection you see every dependency right there and then before even compiling. You provide those dependencies and it will work. With locator you instantiate it and then only during runtime it will fail with the first missing service. Then you add that and it will fail again with the next one. Then after some trial and error it finally works until you call a method on that class that itself also uses the locator to load yet another missing dependency. Repeat ad-infinitum.

E: Can't really answer the question what's good to use for DI in WPF in practice as I was successfully able to avoid having to use it so far, but I can't see why basic stuff like TinyIoC won't work in principle.

SirViver fucked around with this message at 00:43 on Oct 29, 2020

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

necrotic posted:

https://github.com/naudio/NAudio/blob/master/Docs/PlayAudioFileWinForms.md

This approach should also work in a TUI, and seems to have all the niceties you want built in.

Thanks for this! I've worked the ideas into my code and this approach is working great. No more Task.Run() or Mutex.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

LongSack posted:

How do you all implement DI in a WPF project? I find myself using the locator pattern, where there is a Locator class which has a ServiceProvider, registers all the services needed, and exposed properties like
C# code:
public Foo Foo => _provider.GetRequiredService<Foo>();
The Locator service installs a reference to itself in Application.Current.Resources and is accessed by a static method in a Tools class like
C# code:
public static Locator Locator => 
    Application.Current.Resources[”Locator”] as Locator ?? New Locator();
It works, but I’ve read that some people consider the locator to be an anti-pattern, so I’m wondering if there’s a better way.

I never had a problem just using microsoft unity for dependency injection - I've used like five different DI frameworks in .net and frankly I could not give a gently caress about the differences, they all worked.

This article is pretty much how I did it last time. https://stackoverflow.com/questions/36631149/dependency-injection-with-unity-on-wpf-mvvm-application

For service locator, the reason it's bad is that service locator is essentially a fancy way of making all your poo poo static, and it also doesn't really deal with teasing out which services depend on other services so it's a pain in the rear end. Constructor injection is nice because your startup does all the wiring, and you can figure out what all the dependencies of a class are just from looking at the constructor.

Bruegels Fuckbooks fucked around with this message at 01:16 on Oct 29, 2020

MadFriarAvelyn
Sep 25, 2007

epalm posted:

Bonus points if you inject this service via IoC container.

:emptyquote:

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

adaz posted:

The easiest way to accomplish this is to implement what's called a cancellation token. You would wire up your while loop to see if the cancellation token was called. Then you can abort it. Depending on how you want to do this, the easiest thing to do is setup a additional method on your IPlayer interface called Cancel() that just invokes the cancellation token and call that from whatever needs to cancel the audio file.

Just a note here too, you really don't want to be using mutexes inside tasks. I'd delegate that behavior to whatever is calling PlayAudioFile(). On your IPlayer expose a Playing, Stopped Enumeration - just a simple Property - and make whatever is calling IPlayer check the state before invoke PlayAudioFile(). To set the Playing/Stopped Enum you can use a conventional locking mechanism inside your PlayAudioFile()

On a sidenote, do you by any chance have recommendations for books or guides that deal with tasks and threading? I just want to make sure I don't run into any pitfalls (like Mutexes inside of Task.run) again going forward.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Yeah I'm having uncomfortable amounts of success with a ViewModel. Setting a command for a button in the template is letting me run the callback against the button data it represents directly so I don't have to do any lookups or anything. Also, all of the buttons in my template were instantiated and displayed in the designer now. I'm trying to come to terms with how so much stuff just kind of worked. I'm guessing a lot of the stuff around data contexts have grown to assume you use view models of some sort.

One big concern I have is RelayCommand. That isn't stock so I'm trying to figure out where to properly source it without a license issue. I'm not sure how well getting it from a NuGet package is going to work when I move this all to Unity3d and try to use it with NoesisGUI.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Rocko Bonaparte posted:

Yeah I'm having uncomfortable amounts of success with a ViewModel. Setting a command for a button in the template is letting me run the callback against the button data it represents directly so I don't have to do any lookups or anything. Also, all of the buttons in my template were instantiated and displayed in the designer now. I'm trying to come to terms with how so much stuff just kind of worked. I'm guessing a lot of the stuff around data contexts have grown to assume you use view models of some sort.

One big concern I have is RelayCommand. That isn't stock so I'm trying to figure out where to properly source it without a license issue. I'm not sure how well getting it from a NuGet package is going to work when I move this all to Unity3d and try to use it with NoesisGUI.
Generally the data context of your UI should be its view model. That's what makes the pattern work seamlessly.

The original article introducing the RelayCommand is here: https://docs.microsoft.com/en-us/archive/msdn-magazine/2009/february/patterns-wpf-apps-with-the-model-view-viewmodel-design-pattern.

If you use the mvvmlight toolkit http://www.mvvmlight.net/, RelayCommand is part of it and it's under MIT license. https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/may/mvvm-commands-relaycommands-and-eventtocommand. You could just source it through that.

raminasi
Jan 25, 2005

a last drink with no ice
You can just write your own RelayCommand, they’re like ten lines long.

epswing
Nov 4, 2003

Soiled Meat

raminasi posted:

You can just write your own RelayCommand, they’re like ten lines long.

Until you start using async/await and have to write AsyncRelayCommand with all the complexity that comes with it :(

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

epalm posted:

Until you start using async/await and have to write AsyncRelayCommand with all the complexity that comes with it :(

AsyncRelayCommand wasn't much more complex - decent MIT license example was https://johnthiriet.com/mvvm-going-async-with-async-command/.

At least where I've worked nobody cared about nuget sourcing stuff like relaycommand... I've seen projects where devs either control-c control-v stuff like relaycommand / event aggregators or just use stackoverflow links and it's never really been a problem. If it's posted as sample code on the msdn website it's fair game for inclusion in a project under microsoft limited public license. I can understand trying to be thorough about this to ward off legal problems though.

Bruegels Fuckbooks fucked around with this message at 15:56 on Oct 29, 2020

adaz
Mar 7, 2009

Supersonic posted:

On a sidenote, do you by any chance have recommendations for books or guides that deal with tasks and threading? I just want to make sure I don't run into any pitfalls (like Mutexes inside of Task.run) again going forward.

an oldy but a goody on async await TPL best practices from Tech Ed 2014

Async Await best practices from MSDN Magazine.

TPL pitfalls from MSDN

rarbatrol
Apr 17, 2011

Hurt//maim//kill.
Not especially related, but CancellationToken and CancellationTokenSource can do some pretty cool things. One of my personal favorites is CancellationToken.Register which lets you set up a delegate to be called when the cancellation is triggered. The registration itself can be put in a using statement, so if you wanted to, say... call SqlCommand.Cancel for only a specific critical phase of work, it's not only possible, it's easy. Once the registration is disposed, the delegate is no longer registered or called upon cancellation.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Bruegels Fuckbooks posted:

I've seen projects where devs either control-c control-v stuff like relaycommand / event aggregators or just use stackoverflow links and it's never really been a problem.
I'm in for the MVVM approach but I find this pretty amusing. They want everybody to use MVVM but then leave out a pretty common thing that--dare I say, "is a common pattern"--and people just copy-paste it.

I would concede if there really was much variation in what it was doing so that one should write it for their own needs. Even then, everybody is giving it the same name!

raminasi
Jan 25, 2005

a last drink with no ice

Rocko Bonaparte posted:

I'm in for the MVVM approach but I find this pretty amusing. They want everybody to use MVVM but then leave out a pretty common thing that--dare I say, "is a common pattern"--and people just copy-paste it.

I would concede if there really was much variation in what it was doing so that one should write it for their own needs. Even then, everybody is giving it the same name!

Creating functionality that makes a potentially really annoying thing super straightforward but neglecting to implement a crucial, yet simple part of it is extremely on brand for WPF, the framework that makes hard things easy and easy things hard.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

raminasi posted:

Creating functionality that makes a potentially really annoying thing super straightforward but neglecting to implement a crucial, yet simple part of it is extremely on brand for WPF, the framework that makes hard things easy and easy things hard.

Part of the problem is that the developers of WPF hated being constrained by "frameworks" and wanted wpf to be very open ended and to make it so the UI isn't an anchor on your code. I think they largely succeeded in that goal, but man are React and Angular easier to deal with than WPF.

I also do hate that stuff like "how do I put an enum in a combo box and bind it to my viewmodel?" or "how do I do radio buttons correctly" invariably ends up with a long stack overflow article with people arguing about value converters.

No Pants
Dec 10, 2000


David Fowler's writeup is also a nice introduction to this stuff.

Roid666
Jul 18, 2010
You cannot talk about async await without mentioning Mr Stephen Cleary!

https://blog.stephencleary.com/2012/02/async-and-await.html

distortion park
Apr 25, 2011


rarbatrol posted:

Not especially related, but CancellationToken and CancellationTokenSource can do some pretty cool things. One of my personal favorites is CancellationToken.Register which lets you set up a delegate to be called when the cancellation is triggered. The registration itself can be put in a using statement, so if you wanted to, say... call SqlCommand.Cancel for only a specific critical phase of work, it's not only possible, it's easy. Once the registration is disposed, the delegate is no longer registered or called upon cancellation.

I didn't know the bit about disposable registers, super cool.


I've been doing some node Dev recently and the lack of a "using" pattern really sucks.

Mr Shiny Pants
Nov 12, 2012

Rocko Bonaparte posted:

I'm in for the MVVM approach but I find this pretty amusing. They want everybody to use MVVM but then leave out a pretty common thing that--dare I say, "is a common pattern"--and people just copy-paste it.

I would concede if there really was much variation in what it was doing so that one should write it for their own needs. Even then, everybody is giving it the same name!

This. I just used something like MVVM light. It makes life that much easier.

epswing
Nov 4, 2003

Soiled Meat

Mr Shiny Pants posted:

This. I just used something like MVVM light. It makes life that much easier.

I think mvvmlight is nice. I've been following this thread for a while https://github.com/lbugnion/mvvmlight/issues/69

Incoming personal opinion: If you build an open source project with the intention of it being widely used (i.e. not a personal hobby project), then it's your responsibility to either maintain it, or gracefully abandon it by handing over the reigns. If you are able (i.e. you're not dead or homeless), you shouldn't just ghost the entire user base.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

epalm posted:

I think mvvmlight is nice. I've been following this thread for a while https://github.com/lbugnion/mvvmlight/issues/69

Incoming personal opinion: If you build an open source project with the intention of it being widely used (i.e. not a personal hobby project), then it's your responsibility to either maintain it, or gracefully abandon it by handing over the reigns. If you are able (i.e. you're not dead or homeless), you shouldn't just ghost the entire user base.

It's a legitimate opinion. My opinion is that releasing open source code for free is an act of kindness by itself, and it's your responsibility as a user, when you choose to depend on an open source project for which you did not purchase a support contract, to have a plan in place in the event that the maintainer(s) are run over by a bus or decide to do something else with their lives.

epswing
Nov 4, 2003

Soiled Meat

NihilCredo posted:

It's a legitimate opinion. My opinion is that releasing open source code for free is an act of kindness by itself, and it's your responsibility as a user, when you choose to depend on an open source project for which you did not purchase a support contract, to have a plan in place in the event that the maintainer(s) are run over by a bus or decide to do something else with their lives.

I like your opinion. I think my opinion and your opinion can co-exist. I agree that you should have a plan in case your dependency becomes unavailable, this sometimes even happens when you have a support contract but a business relationship changes. But locking a project in a GitHub repo and throwing away the key, while software projects and package managers and users all reference it, chips away at that original act of kindness.

I respect the decision to walk away, just give someone else the key, willya?

B-Nasty
May 25, 2005

NihilCredo posted:

it's your responsibility as a user, when you choose to depend on an open source project for which you did not purchase a support contract, to have a plan in place in the event that the maintainer(s) are run over by a bus or decide to do something else with their lives.

100%, especially if you're using this OSS library/tool in a project for your employer.

I found this to be one of those lines between junior engineers and actual senior engineers. A seasoned engineer will research a OSS project thoroughly to vet its main contributors and overall repo activity. On top of that, a good engineer will design abstractions around the use of the library to make it easier to substitute another option if necessary later.

Always prefer highly-active, popular libraries over newer options. Take a 'wait and see' approach to newer stuff to ensure it has staying power (this applies to Microsoft's stuff as well)

Mr Shiny Pants
Nov 12, 2012

epalm posted:

I think mvvmlight is nice. I've been following this thread for a while https://github.com/lbugnion/mvvmlight/issues/69

Incoming personal opinion: If you build an open source project with the intention of it being widely used (i.e. not a personal hobby project), then it's your responsibility to either maintain it, or gracefully abandon it by handing over the reigns. If you are able (i.e. you're not dead or homeless), you shouldn't just ghost the entire user base.

It's been some years since I last used it. But the one thing that stood out to me was all the half-baked WPF stuff it solved.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.
The whole experience with learning WPF and XAML is essentially trolling because most of the time if you try to use something like a UI tookit or a library to do something, you only need to understand the subset of the library necessary for what you want to do, and don't have to read article on article about the overarching philosophy of ***. With WPF, I initially approached it like "this is not cryptography, this is just putting a window with controls on it on a computer screen, why do I need to read all these articles or care about poo poo like view models?" Having that mindset will absolutely kill you with WPF because the framework will give you all the tools you need to hang yourself with monumentally lovely code, and actually taking the time to learn and understand the patterns makes the coding actually trivial.

Mr Shiny Pants
Nov 12, 2012

Bruegels Fuckbooks posted:

The whole experience with learning WPF and XAML is essentially trolling because most of the time if you try to use something like a UI tookit or a library to do something, you only need to understand the subset of the library necessary for what you want to do, and don't have to read article on article about the overarching philosophy of ***. With WPF, I initially approached it like "this is not cryptography, this is just putting a window with controls on it on a computer screen, why do I need to read all these articles or care about poo poo like view models?" Having that mindset will absolutely kill you with WPF because the framework will give you all the tools you need to hang yourself with monumentally lovely code, and actually taking the time to learn and understand the patterns makes the coding actually trivial.

This is what I meant, if you want to do it the "right" way you need to code a lot of scaffolding first. Which is one the reasons, I guess, why it never really took off.

Canine Blues Arooo
Jan 7, 2008

when you think about it...i'm the first girl you ever spent the night with

Grimey Drawer

Bruegels Fuckbooks posted:

The whole experience with learning WPF and XAML is essentially trolling because most of the time if you try to use something like a UI tookit or a library to do something, you only need to understand the subset of the library necessary for what you want to do, and don't have to read article on article about the overarching philosophy of ***. With WPF, I initially approached it like "this is not cryptography, this is just putting a window with controls on it on a computer screen, why do I need to read all these articles or care about poo poo like view models?" Having that mindset will absolutely kill you with WPF because the framework will give you all the tools you need to hang yourself with monumentally lovely code, and actually taking the time to learn and understand the patterns makes the coding actually trivial.

This is a gospel truth and it really, really sucks because some of those important patterns seem either estoric or needlessly verbose, especially on a first read. I actually really like WPF, but I've written some pretty trashy poo poo on my journey to writing slightly less trashy poo poo now, and almost all of it was borne from an attitude of, 'This seems needlessly complex/annoying to implement/boilerplate for the sake of boilerplate and I probably don't actually *need* it...

Nth Doctor
Sep 7, 2010

Darkrai used Dream Eater!
It's super effective!


rarbatrol posted:

Not especially related, but CancellationToken and CancellationTokenSource can do some pretty cool things. One of my personal favorites is CancellationToken.Register which lets you set up a delegate to be called when the cancellation is triggered. The registration itself can be put in a using statement, so if you wanted to, say... call SqlCommand.Cancel for only a specific critical phase of work, it's not only possible, it's easy. Once the registration is disposed, the delegate is no longer registered or called upon cancellation.

That's loving awesome

I did a tech talk for my department earlier this year demonstrating how to use cancellation tokens responsibly to ensure you don't unnecessarily bail out of a chunk of work mid-way.

I used the notion of being a 21st Century Fox exec choosing shows to cancel:
Firefly stops immediately when the cancellation token is triggered
Dollhouse finishes a season once the cancellation token is triggered
KVille cancels itself (oh no a writers' strike!)
The Simpsons never checks the cancellation token and runs forever.

I was able to demonstrate how to issue tokens, check them yourself, link multiple tokens together, and trigger visceral rage all in 15 minutes.

raminasi
Jan 25, 2005

a last drink with no ice
The WPF thing I wish I could go back in time and tell myself is “make a conscious architectural decision every time you add INotifyPropertyChanged to something, don’t just subscribe everything to everything willy-nilly.”

Mr Shiny Pants
Nov 12, 2012
Model View Update is so much more simple and elegant.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
WPF is annoying the hell out of my but I'm still getting further quicker with less code than the shenanigans I was doing in Unity 3d using its GUI system. Now to contradict myself by posting about my next hiccup with it:

I want to prompt when the user selects to overwrite a save. I created a UserControl to show the prompt and a view model to manage the prompt and choices. The command to overwrite the save is in the ViewModel for the save button. Everything became a mess when I tried to insert it there. I needed a back-reference to my main screen, which I then had to plumb all the way from my root ViewModel. But lo, I need a parameterless constructor, so I had to add it after initial creation. Then the saves wouldn't display because I was filling my container afterwards. I even set up INotifyChanged and fired OnPropertyChanged for the container--which is an ObservableCollection<> in the first place.

I don't think the solution is figuring out how to get the way I did it to work. That whole thing just stinks. I'm guessing I should hook something up in the XAML for the save buttons but I don't know what. Well, I can do something, but I don't know how I block on the prompt and then carry over to the button's code to apply itself when the user accepts the prompt. What's the least painful way to manage this?

Note that I can't use Window and its ilk in Unity 3d; my main window is using it right now for screwing around but it'll eventually become a UserControl too. So I gave up on using system modal dialogs here. Also, I assumed the system modals would class with the GUI's aesthetic anyways; I'm guessing most people don't use them in WPF (?).

Adbot
ADBOT LOVES YOU

mystes
May 31, 2006

Are you sure you really mean system modal dialog boxes?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply