views:

564

answers:

1

Okay, similar questions exist, but they are all about how to determine this from outside of the entity itself and use the DataContext the entity is attached to.

I am binding my entities to an edit form in WPF. Within a DataTemplate, I want to be able to set the background color of the root container within a DataTemplate to show it has been changed and these changes have not yet been submitted to the database.

Here's a very simple sample that demonstrates what I'm talking about (forgive errors):

<Page ...>
  <Page.DataContext>
    <vm:MyPageViewModel /> <!-- holds reference to the DataContext -->
  </Page.DataContext>
  <ItemsControl
    ItemsSource = {Binding Items}>
      <ItemsControl.Resources>
        <DataTemplate 
          DataType="Lol.Models.Item"> <!-- Item is L2S entity -->
          <!-- IRL I use styles to set the background color -->
          <TextBlock Text="{Binding IsDirty, StringFormat='Am I dirty? /{0/}'}"/>
        </DataTemplate>
      </ItemsControl.Resources>
  </ItemsControl>
</Page>

The example just prints out "Am I dirty? yes" or "Am I dirty? no", but you get the idea.

To do this, I'll need to add a public property to my Item (partial class, simple) that can determine if the entity is dirty or not. This is the tough bit.

public partial class Item
{
    public bool IsDirty
    {
        get
        {
          throw new NotImplementedException("hurf durf");
        }
    }
}

Outside of the entity its pretty simple (as long as you have the DataContext the entity is attached to). Inside, not so much.

What are my options here?


Wiki now. I don't think there's any one good solution here, so suggestions for workarounds are welcome.

+3  A: 

If you are using the dbml generated classes, you should be able to implement a couple of partial methods like this:

public partial class SampleEntity
{
    partial void OnCreated()
    {
        this.IsDirty = true;
    }

    partial void OnLoaded()
    {
        this.PropertyChanged += (s, e) => this.IsDirty = true;
        this.IsDirty = false;
    }

    public bool IsDirty { get; private set; }
}
ongle
The use of the lambda here is pure evil. I like it.
Dave Markle
I considered something like this, but it doesn't take into account the original state of the entity. So false dirties are possible, I believe. What's a good way to go about preventing that?
Will
I don't understand what you mean, could you give me an example?
ongle
The false dirties could happen if the property is changed, then changed back to the original value. in the Property Changed event there is no way to tell if the sender's value is different than the original's value (I tried using reflection), and I didn't have luck with the PropertyChanging event (since linq2Sql doesn't send the property name)
Kevin
@klogan - what you are looking for is more than the dbml code gen does for you. I ended up creating my own linq2sql code gen tool to add features I wanted, change the reference property naming and correct the on change events to let you know what property was changing. To track original values you would have to edit or subclass the dbml classes or do your own code gen. Have you looked into the entity framework instead?
ongle
Accepting as an answer; there is no good solution unless you do what @ongle did.
Will