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.
 
  • Locked thread
Fuck them
Jan 21, 2011

and their bullshit
:yotj:

Ithaqua posted:

That all looks like good, well-factored code. I think what you're missing is the implementation in the base classes.

So this is the feeling of bad development and bad habits leaving the body. It's just painful because I'm impatient and it's big, huh?

I had a feeling it was done right, but I couldn't tell if it's just not being used to a BIG PROJECT or if it's a case of something being wrong.

One thing that makes me go "hrm" is the fact that there are classes with the same name, though some are subclasses of different base classes, i.e. there could be FooClass, and SomeBase.FooClass. This made my head hurt.

Is this a normal idiom?

Adbot
ADBOT LOVES YOU

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

2banks1swap.avi posted:

So this is the feeling of bad development and bad habits leaving the body. It's just painful because I'm impatient and it's big, huh?

I had a feeling it was done right, but I couldn't tell if it's just not being used to a BIG PROJECT or if it's a case of something being wrong.

One thing that makes me go "hrm" is the fact that there are classes with the same name, though some are subclasses of different base classes, i.e. there could be FooClass, and SomeBase.FooClass. This made my head hurt.

Is this a normal idiom?

That might be okay or might not be. It depends on the actual names of the classes and how they're used.

For example:
code:
public class Trunk {} // as in a tree trunk
public class Elephant 
{
	private class Trunk {}
}

public class Car
{
	private class Trunk {}
}
A tree Trunk, an Elephant.Trunk, and a Car.Trunk are all different things even though they have the same name.

Also, please please please tell everyone there to not catch exceptions just to wrap them up and rethrow them. That's retarded.

Fuck them
Jan 21, 2011

and their bullshit
:yotj:
Next week will be my third on the calendar and the first where I didn't either start on a Tuesday or have Thursday and Friday off, so I'll bring it up as meek as I can so I'm not glared at.

Gut says that exception-stuff is most likely just the result of generated code, but FIIK.

Dietrich
Sep 11, 2001

Single Responsibility Principle (the s in SOLID) leads you to creating a lot of classes with only one or two methods in them. What you're looking at is not that uncommon.

The thing that is a little scratch your head is that they've got two layers of things called repositories. One for models <-> business objects, another for business objects <-> database objects.

I generally do all my model <-> business object stuff directly in the controller, because models are (or should be imho) controller/view specific (as they are a UI concern). And then you've got to have some classes somewhere that spit out business objects from the database and take business objects and persist them to the database.

Fuck them
Jan 21, 2011

and their bullshit
:yotj:

Dietrich posted:

Single Responsibility Principle (the s in SOLID) leads you to creating a lot of classes with only one or two methods in them. What you're looking at is not that uncommon.

The thing that is a little scratch your head is that they've got two layers of things called repositories. One for models <-> business objects, another for business objects <-> database objects.

I generally do all my model <-> business object stuff directly in the controller, because models are (or should be imho) controller/view specific (as they are a UI concern). And then you've got to have some classes somewhere that spit out business objects from the database and take business objects and persist them to the database.

That made it so much more clear. Just, wow.

gnatalie
Jul 1, 2003

blasting women into space
Although I'm not a good enough programmer to help with your main questions, I noticed two minor things that will make your code look a bit nicer. First,

Visual Basic .NET code:
If ValidationContext.IsValid Then
    viewModel.IsValid = True
Else
    viewModel.IsValid = False
End If
can be turned into

Visual Basic .NET code:
viewModel.IsValid = ValidationContext.IsValid
Second, there's the VB exclusive With statement:

Visual Basic .NET code:
...
adult$TASKs.ClientPIN = viewModel.ClientPIN
adult$TASKs.CasePIN = viewModel.CasePIN
adult$TASKs.$TASK = viewModel.Notes
adult$TASKs.DateCreated = DateTime.Now.ToString
...
command.Parameters.Add(New SqlParameter("ClientPIN", model.ClientPIN))
command.Parameters.Add(New SqlParameter("ClientNote ", model.$TASK))
command.Parameters.Add(New SqlParameter("CasePIN ", model.CasePIN))
command.Parameters.Add(New SqlParameter("CreateUser ", model.CreateUser))
becomes

Visual Basic .NET code:
...
With adult$TASKs
    .ClientPIN = viewModel.ClientPIN
    .CasePIN = viewModel.CasePIN
    .$TASK = viewModel.Notes
    .DateCreated = DateTime.Now.ToString
End With
...
With command.Parameters
    .Add(New SqlParameter("ClientPIN", model.ClientPIN))
    .Add(New SqlParameter("ClientNote ", model.$TASK))
    .Add(New SqlParameter("CasePIN ", model.CasePIN))
    .Add(New SqlParameter("CreateUser ", model.CreateUser))
End With

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Dietrich posted:

I generally do all my model <-> business object stuff directly in the controller, because models are (or should be imho) controller/view specific (as they are a UI concern). And then you've got to have some classes somewhere that spit out business objects from the database and take business objects and persist them to the database.

I generally mediate all of my controller interactions with another layer.

FooController -> FooTasks -> FooRepository.

The controller gives the model to FooTasks, which in turn translates the model into a business object that goes to the FooRepository. The upside there is that any sort of lower-level representation of the data is nicely hidden from the controller. The controller shouldn't need to know how the data looks when it's getting persisted.

aBagorn
Aug 26, 2004

Ithaqua posted:

I generally mediate all of my controller interactions with another layer.

FooController -> FooTasks -> FooRepository.

The controller gives the model to FooTasks, which in turn translates the model into a business object that goes to the FooRepository. The upside there is that any sort of lower-level representation of the data is nicely hidden from the controller. The controller shouldn't need to know how the data looks when it's getting persisted.

This is along the lines of how I'm doing things as well. My controllers are dumb by design.

zokie
Feb 13, 2006

Out of many, Sweden

Ithaqua posted:

I generally mediate all of my controller interactions with another layer.

FooController -> FooTasks -> FooRepository.

The controller gives the model to FooTasks, which in turn translates the model into a business object that goes to the FooRepository. The upside there is that any sort of lower-level representation of the data is nicely hidden from the controller. The controller shouldn't need to know how the data looks when it's getting persisted.

This is some good poo poo, and definitively how I'm going to structure my MVC apps from now on. And on a side note I made the effort to learn T4-templates today, now I wan't to code-generate all the code :getin:

Still most of the plumbing that needs to be generated/made is either because WCF doesn't handle generics (can't be avoided), because my boss/colleagues don't seem to comfortable generics (ugh) or that it was decided to only use one WCF-service for client-server communication (:stare:, countless businessobjects all with CRUD, GetById and GetAll at a minimum). Luckily almost everyone is on vacation and won't be able to stop me from at least segregating the service interface... But any way, T4-tempating is really neat.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

zokie posted:

This is some good poo poo, and definitively how I'm going to structure my MVC apps from now on. And on a side note I made the effort to learn T4-templates today, now I wan't to code-generate all the code :getin:

Still most of the plumbing that needs to be generated/made is either because WCF doesn't handle generics (can't be avoided), because my boss/colleagues don't seem to comfortable generics (ugh) or that it was decided to only use one WCF-service for client-server communication (:stare:, countless businessobjects all with CRUD, GetById and GetAll at a minimum). Luckily almost everyone is on vacation and won't be able to stop me from at least segregating the service interface... But any way, T4-tempating is really neat.

I've done two things with T4:
1) Email templates (insert customer's name, product info, etc), which was much nicer than the old solution.
2) A full parameterization library, mainly intended for testing. You can specify test parameters on an environment-by-environment basis (based on compilation symbols) in a spreadsheet (or a series of spreadsheets) and T4 sucks the spreadsheet in and spits out a nice class hierarchy. It's been very useful for our clients that do Coded UI tests on multiple environments where results tend to differ because Environment A returns 30 records but environment B returns 4326.

Quebec Bagnet
Apr 28, 2009

mess with the honk
you get the bonk
Lipstick Apathy

2banks1swap.avi posted:

Would multi-thread-debugging allow you to manually trigger the likes of spinlocks or mutexes or whatever?

Or would you have separate "step throughs" for each thread? :psypop:

You'd see your breakpoints which are only supposed to be hit once being hit multiple times, for example. I'm proud of myself for only taking 15 minutes to figure out that a particular library I was using didn't document the fact that my callbacks would be called from multiple threads.

crashdome
Jun 28, 2011

Ithaqua posted:

A tree Trunk, an Elephant.Trunk, and a Car.Trunk are all different things even though they have the same name.


And then the UK branch refactors Car.Trunk to Car.Boot and all the US developers jump from windows.

Sab669
Sep 24, 2009

Any of you guys know of a cool, preferably free query-building tool? I've been using this and it works pretty well, except for when I need to use some sort of IN clause, in which case its support is just awful.

epswing
Nov 4, 2003

Soiled Meat
Does anyone know of or have any examples of a well-structured best-practices ASP.NET MVC 4 application? I'm looking for something medium sized to learn from. By medium sized I mean not a toy/trivial example, but not an enterprise solution either.

Dietrich
Sep 11, 2001

epalm posted:

Does anyone know of or have any examples of a well-structured best-practices ASP.NET MVC 4 application? I'm looking for something medium sized to learn from. By medium sized I mean not a toy/trivial example, but not an enterprise solution either.

Look at how Ruby on Rails projects are structured.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Dietrich posted:

Look at how Ruby on Rails projects are structured.

Except in RoR it's not uncommon to have heavy models, which is generally opposite how things are done in .NET-land.

https://github.com/BobPalmer/RobotParts

This is a pretty good demo a former co-worker of mine put together. We've used it for demoing testing (coded UI, unit testing, BDD with specflow, etc).

Funking Giblet
Jun 28, 2004

Jiglightful!
I don't think it's uncommon to have heavy models, or domain driven models. Anaemic models serve little purpose. You have a tasks folder which does all the logic for your domain, it should really form part of the domain. That example has 14 projects! Overkill, you could have a Core business project, and an MVC project and a unit test project. That's all you need for a medium size project.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Funking Giblet posted:

I don't think it's uncommon to have heavy models, or domain driven models. Anaemic models serve little purpose. You have a tasks folder which does all the logic for your domain, it should really form part of the domain. That example has 14 projects! Overkill, you could have a Core business project, and an MVC project and a unit test project. That's all you need for a medium size project.

It's not my code, but I still think it's reasonable.
  • Test projects are split apart by type, which represents the bulk of the projects (5). Tests should be segregated by type, both for organization and for CI purposes -- I don't want to run my UI or integration tests on every check-in.
  • The UI is split into models, views, and controllers. (3 projects) There's no good reason to keep the three of them together. The controller is testable completely independently of anything else. I could see the argument being made for keeping the controller and model together, but the model can be (and is) used in places where the controller isn't necessary.
  • The database persistence layer is split into three projects: "Persistence", "Repository", and "Model". This is because all of the necessary interfaces are in the "Repository" project. The "Repository" is a seam for testing. There's no need to bring the persistence layer in to test anything other than persistence.
  • Miscellaneous: The two Ninject projects
  • "Tasks". I don't think that the logic here belongs anywhere else.

That said, when I'm starting something new, I do start with as few projects as possible and split them apart only when it makes sense. Generally, that means "UI", "Core", and "Tests". The "Core" project always ends up getting deleted eventually, as things migrate naturally to a more specific location.

Funking Giblet
Jun 28, 2004

Jiglightful!

Ithaqua posted:

It's not my code, but I still think it's reasonable.
  • Test projects are split apart by type, which represents the bulk of the projects (5). Tests should be segregated by type, both for organization and for CI purposes -- I don't want to run my UI or integration tests on every check-in. Most frameworks support categories of tests which can be filtered with a parameter.
  • The UI is split into models, views, and controllers. (3 projects) There's no good reason to keep the three of them together. The controller is testable completely independently of anything else. I could see the argument being made for keeping the controller and model together, but the model can be (and is) used in places where the controller isn't necessary. I used to do this, but a folder is good enough, the model should be a rich model stored as a core project, the mvc project is a front end project
  • The database persistence layer is split into three projects: "Persistence", "Repository", and "Model". This is because all of the necessary interfaces are in the "Repository" project. The "Repository" is a seam for testing. There's no need to bring the persistence layer in to test anything other than persistence. I don't use a repository, just the NHIB ISession directly, and it's testable using SQLLite or something. That's a personal choice for me though.
  • Miscellaneous: The two Ninject projects Two ninject projects? This is infrastructure usually only required in the front end project, dump it into a folder, any reusable parts can maybe be pushed to a common frontend project. Ninject is also a dependency inside of a controller, this is bad
  • "Tasks". I don't think that the logic here belongs anywhere else. It looks like core business logic

That said, when I'm starting something new, I do start with as few projects as possible and split them apart only when it makes sense. Generally, that means "UI", "Core", and "Tests". The "Core" project always ends up getting deleted eventually, as things migrate naturally to a more specific location.

Commented above. Now, I'm not saying I'm right or wrong, but that's just how I would see the above. 15 projects is really annoying to deal with, especially with a small team of people who need to jump around a lot.

Funking Giblet fucked around with this message at 21:33 on Jul 6, 2013

Milotic
Mar 4, 2009

9CL apologist
Slippery Tilde
15 projects, some of which only contain one class other than AssemblyInfo.cs is daft. That many projects, you end up having to do contortions like defining an interface in one project and concrete implementations much further down the build chain because there's another project dependency the concrete implementation needs. I'm also guessing that that many projects probably adds to the build time slightly instead of if there were 3 or 4.

In terms of documentation it's not great - A comment in the relevant places why some of the models are structs instead of classes would be nice (unless that's the current convention when using nHibernate as an ORM). I'm a bit of a zealot and think if a type is public, it should have a <summary> tag at the class level, even if it's obvious what it does.

wwb
Aug 17, 2004

To pile on, it looks like alot of the projects using that onion architecture pattern that was the .NET community's response to the previous standard of a "big ball of mud attached to the UI codebehind" pattern that had been the common parlance before.

epswing
Nov 4, 2003

Soiled Meat
All of you RobotParts haters aren't making any other suggestions..

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

epalm posted:

All of you RobotParts haters aren't making any other suggestions..

Funking Giblet made another suggestion. At a high level, the way you want to organize any project with a UI is:

  • UI project that contains just your UI-related stuff (XAML, HTML/JavaScript, whatever else)
  • Business logic project(s) that contain controllers, models, and any other sort of business logic stuff that's unrelated to how the data is displayed
  • Test project(s) to test the business logic project(s)

How you choose to split everything up beyond that is a matter of opinion.

epswing
Nov 4, 2003

Soiled Meat

Ithaqua posted:

  • Business logic project(s) that contain controllers, models, and any other sort of business logic stuff that's unrelated to how the data is displayed

How you choose to split everything up beyond that is a matter of opinion.

Ok, this right here is what I'd like to learn more about. I realize it's a matter of opinion, and that's what I'm after. What are some .NET business logic project(s) that properly implement
  • database access
  • data access objects
  • data transfer objects
  • dependency injection

My projects tend to use poor mans DI, automapper to translate from DAO to DTO, and some manual methods to get from DTO back to DAO (ie user edits DTO and clicks save). It all works, but I'm sure I have a variety of things in the wrong place, and I'm just looking for a more established, formal example.

epswing fucked around with this message at 07:39 on Jul 9, 2013

Funking Giblet
Jun 28, 2004

Jiglightful!
Here's an example I've just quickly setup.

https://github.com/gibletto/ExampleStructure

mortarr
Apr 28, 2005

frozen meat at high speed

Just going to shamelessly rip off your FrontEnd.Infrastructure layout style, that's way nicer than my current method of throwing the whole lot under FrontEnd.App_Start in a big old mess.

edmund745
Jun 5, 2010
Using VB in Visual Studio Express 2012: is there any way to set focus to a scrollbar control that doesn't cause it to blink gray off and on?
-----
I have a form with a combobox that chooses among about 28 choices--24 different schedule charts and four other summary reports.

I noticed early on that the combobox likes to keep focus, and if the scrollwheel is moved then that changes the combobox selection, which is absolutely horrible/totally useless, considering the order of steps regarding how the application gets used. So I want to get the focus "off" that combobox when the mouse leaves it. This is 100% certain, even if the focus can't be moved to any other useful control....

There is also a vertical scrollbar for the charts because some of them end up way taller than the screen.... and hooking to the scrollwheel would be great for that control. So the solution here seems easy, but if I use the combobox's "mouseleave" event to set focus to the scrollbar, that works correctly-----but the scrollbar blinks gray off and on, which is kinda distracting considering that it never does that at any other time. How can I get around that?

One (possibly-boneheaded) idea was to set the [leavecombobox] event to change the focus to a hidden numeric updown control, and then use THAT value to control the scrollbar.

?

I know a lot of programs let you scroll vertically with the mousewheel, but none of them blink like this. It's probable that none of them were written in plain-VB tho'.

beuges
Jul 4, 2005
fluffy bunny butterfly broomstick
If you want to scroll a control using the scroll wheel, focus the control itself, not the scrollbars. So, if the scrollbars are attached to a panel, focus the panel itself instead.

edmund745
Jun 5, 2010

beuges posted:

If you want to scroll a control using the scroll wheel, focus the control itself, not the scrollbars. So, if the scrollbars are attached to a panel, focus the panel itself instead.
There aint none.
I didn't use the picturebox-in-a-panel way because I didn't want the scrollbars to take up the whole bottom and right side of the picture's edge. I needed to put other buttons there, due to the target PCs' low res computer screens (1024 x 768).

The scrollbars change an X/Y offset and redraw a portion of a chart onto a bitmap according to those offsets.

Zhentar
Sep 28, 2003

Brilliant Master Genius
Then your best option is going to be a windows message hook to capture the mouse scroll wheel messages and send them to the scroll bar.

RED TEXT BIG GUN
Sep 1, 2001

Taco Defender
After bumbling through some WPF stuff at work I wanted to get a better grasp on how WPF and MVVM should actually be done. I found this (http://waf.codeplex.com/) and spent a free afternoon looking through it and trying to apply the same sort of concepts to my own code. I finished the day only feeling slightly less lost than before. A few questions:

1. I'm willing to buy a book to get through the learning curve. Any recommendations? I'm more interested in the MVVM, code organization, and threading side of things. I don't want a book that's 70% going through what each WPF control does and how to edit the XAML manually.

2. This is something I'm hoping I can grasp better with a book...

In the couple of small toy programs I wrote I needed to do (thing that takes a while) at program start up. One example was waiting for a process acting as a WCF server to start up and accept my connection. Right now I left this totally synchronous and I'm stalling out the UI. I'm on .NET 4.0 so the await/async discussed a page or two back won't work for me (I think?)

I basically want the UI to pop up as soon as it can and show "Connecting to server..." until I connect without showing hourglasses when I mouse over the window. There seems to be several async options and I think that's what's confusing me. Do I use Task, BackgroundWorker, DispatchTimer, ThreadPool, something else I haven't found yet?

3. Is INotifyPropertyChanged really that terrible or am I missing something entirely?

code:
private string _firstName;

public string FirstName
{
   get { return _firstname; }
   set
   {
      if (_firstname != value)
      {
          _firstname = value;
          OnPropertyChanged("FirstName")
      }
   }
}
For every drat property? And that string that much match the property name? I blew 25 minutes today hunting down a string that I had fat fingered.

ljw1004
Jan 18, 2005

rum

VVildo posted:

I'm on .NET 4.0 so the await/async discussed a page or two back won't work for me (I think?)

If you can switch to VS2012, you can still target .NET4 and use async/await (via the NuGet package Microsoft.Bcl.Async). This is the best option.


quote:

3. Is INotifyPropertyChanged really that terrible or am I missing something entirely?

Is it is really that terrible. You're missing one small bit though...

code:
void OnPropertyChanged([CallerMemberName] string memberName="") {
   var e = PropertyChanged; if (e!=null) e(new PropertyChangedEventArgs(memberName));
}

...
OnPropertyChanged();
This avoids you having to get the string correct. [CallerMemberName] is only recognized by the C#5/VB11 compilers, i.e. it requires VS2012. Also, System.Runtime.CompilerServices.CallerMemberNameAttribute is defined in .NET45, so if you're targeting .NET4 you'll have to define the attribute yourself, or use something like the NuGet package "Microsoft.Bcl" which defines it for you.



Edit: heck, you might even consider storing all your backing fields just in a Dictionary<string,object>. That way, getters & setters can be factored into something fairly small.

code:
public string Fred {get {return (string)Get();} set {Set(value);}



private Dictionary<string,object> _fields = new Dictionary<string,object>();

private object Get([CallerMemberName] string m = "")
{
   object o; _fields.TryGetValue(m,ref o); return o;
}

private void Set(object v, [CallerMemberName] string m = "")
{
   _fields[m] = v;
   var e = PropertyChanged; if (e==null) return;
   e(new PropertyChangedEventArgs(m));
}

ljw1004 fucked around with this message at 01:55 on Jul 10, 2013

GoodCleanFun
Jan 28, 2004

VVildo posted:

After bumbling through some WPF stuff at work I wanted to get a better grasp on how WPF and MVVM should actually be done. I found this (http://waf.codeplex.com/) and spent a free afternoon looking through it and trying to apply the same sort of concepts to my own code. I finished the day only feeling slightly less lost than before. A few questions:

1. I'm willing to buy a book to get through the learning curve. Any recommendations? I'm more interested in the MVVM, code organization, and threading side of things. I don't want a book that's 70% going through what each WPF control does and how to edit the XAML manually.

2. This is something I'm hoping I can grasp better with a book...

In the couple of small toy programs I wrote I needed to do (thing that takes a while) at program start up. One example was waiting for a process acting as a WCF server to start up and accept my connection. Right now I left this totally synchronous and I'm stalling out the UI. I'm on .NET 4.0 so the await/async discussed a page or two back won't work for me (I think?)

I basically want the UI to pop up as soon as it can and show "Connecting to server..." until I connect without showing hourglasses when I mouse over the window. There seems to be several async options and I think that's what's confusing me. Do I use Task, BackgroundWorker, DispatchTimer, ThreadPool, something else I haven't found yet?

3. Is INotifyPropertyChanged really that terrible or am I missing something entirely?

code:
private string _firstName;

public string FirstName
{
   get { return _firstname; }
   set
   {
      if (_firstname != value)
      {
          _firstname = value;
          OnPropertyChanged("FirstName")
      }
   }
}
For every drat property? And that string that much match the property name? I blew 25 minutes today hunting down a string that I had fat fingered.

Check out the practical use at the bottom of the following link:
http://digitaltapestry.wordpress.com/2009/03/20/reflecting-on-code/

Night Shade
Jan 13, 2013

Old School

GoodCleanFun posted:

Check out the practical use at the bottom of the following link:
http://digitaltapestry.wordpress.com/2009/03/20/reflecting-on-code/

Caliburn Micro uses this in its PropertyChangedBase, along with some thread marshalling stuff. The ability to refactor and not have to worry about breaking all of the property changed magic strings is totally worth the tiny overhead and the slightly obscure PropertyChanged(()=>Property) instead of PropertyChanged("Property").

Another related trick: never null-check an event again. Declare them as:
code:
public event EventHandler<EventArgs> SomethingHappened = delegate{};
The empty delegate invocation is basically free, and since nothing outside your class can remove it SomethingHappened will never be null so you can omit the check.

crashdome
Jun 28, 2011

Night Shade posted:

SomethingHappened will never be null so you can omit the check.

Omg I love you.

epswing
Nov 4, 2003

Soiled Meat

VVildo posted:

Is INotifyPropertyChanged really that terrible or am I missing something entirely?

I don't think it's that bad. It's an observable pattern, you have to notify the UI of property changes somehow. This gives you fine-grained control of precisely when that occurs.

I've been using the following class to avoid fat-finger string manipulation:

C# code:
public abstract class BaseNotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    protected void RaisePropertyChanged<TProperty>(Expression<Func<TProperty>> property)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(GetPropertyName(property));
    }

    private string GetPropertyName<TProperty>(Expression<Func<TProperty>> property)
    {
        var lambda = (LambdaExpression)property;

        MemberExpression memberExpression = lambda.Body is UnaryExpression
            ? (MemberExpression)((UnaryExpression)lambda.Body).Operand
            : (MemberExpression)lambda.Body
            ;

        return memberExpression.Member.Name;
    }
}
By inheriting BaseNotifyPropertyChanged, your earlier snippet would become

C# code:
private string _firstName;

public string FirstName
{
   get { return _firstname; }
   set
   {
      if (_firstname != value)
      {
          _firstname = value;
          RaisePropertyChanged(() => FirstName);
      }
   }
}
Note that if you use VS to rename the property, it renames what you're giving to RaisePropertyChanged too.

E: As ljw1004 says, [CallerMemberName] is a better solution, if you're using VS 2012.

epswing fucked around with this message at 14:54 on Jul 10, 2013

Dietrich
Sep 11, 2001

Use AOP so you never have to write this stupid poo poo.

Post Sharp can do it.

You can even do it with Castle Windsor if you're creative.

Dietrich fucked around with this message at 14:54 on Jul 10, 2013

RED TEXT BIG GUN
Sep 1, 2001

Taco Defender
Thanks everyone. That helped at lot.

code:
public event EventHandler<EventArgs> SomethingHappened = delegate{};
I will for sure be using that.

The dynamic proxy stuff from this link looks really cool and kind of what I expected a solution to look like.

Uziel
Jun 28, 2004

Ask me about losing 200lbs, and becoming the Viking God of W&W.

Dietrich posted:

Use AOP so you never have to write this stupid poo poo.

Post Sharp can do it.

You can even do it with Castle Windsor if you're creative.
Thanks for this. I'd heard of PostSharp before but never really looked into it and even though we aren't doing anything with MVVM/WPF, this may be a big help in simplifying some cumbersome and repetitive code.

Adbot
ADBOT LOVES YOU

epswing
Nov 4, 2003

Soiled Meat
nm..

epswing fucked around with this message at 19:37 on Jul 10, 2013

  • Locked thread