0

I've searched on many threads but I couldn't find anything to solve my problem, and I don't really know what keywords I should use. I have a DataGrid which is populated by a DataSet, with columns that I specify manually.

In my column, 'Total', the Binding is set by :

<DataGridTextColumn Header="Total"
         Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                   AncestorType={x:Type UserControl}},
                   Path=DataContext.Total}"

The Total property is not in the DataSet, which is bound to my DataGrid, that's why I use this kind of Binding.

The problem is that when I set a value inside a cell of 'Total', like any user would do, this value is repeated in each cell of my column.

So, I know it is because of this property, since everytime I change my cell's value the Total property gets this new value and sends it back to my column. I could use a condition which uses the selected row's number or something, I have some ideas of what I should do, but I can't do that in my Xaml code.

I tried to create a Binding() in the code behind part but it doesn't really work and I'm not sure it could change anything.

Is there any way to use one value per row in this case ?

Thanks !

Adrana
  • 79
  • 11
  • Easiest way would be to not use a DataSet but rather custom class representing your data. Then you can add a property that represents the total of the other fields and bind your column to that. This will also support using the MVVM design pattern http://msdn.microsoft.com/en-us/magazine/dd419663.aspx – Lee O. Jun 20 '14 at 11:07
  • @LeeO. Hey thanks for your link, I tried to read that when I started in WPF few months ago. Unfortunately, I have no choice but to use a DataSet, that's why I didn't try something else. Actually is represents the total of the other fields, but in each cell in my column, this is the problem. – Adrana Jun 20 '14 at 11:23
  • Add a column to the DataTable within the DataSet that uses an expression to calculate it's value and bind your total column to this column. http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx – Lee O. Jun 20 '14 at 11:50
  • Ok, I'm not sure if I can modify my DataSet but I'll give it a try, thanks for your tip. I guess there's no other solution ? – Adrana Jun 20 '14 at 11:59
  • You could also use a multibinding for your total column and bind it to all the same bindings the columns you want to sum up are bound to. Then create a IMultiValueConverter that will sum up those values. – Lee O. Jun 20 '14 at 12:11
  • I may be misinterpreting what you want to do. I don't understand why you say you have no choice but to use a DataSet. Once you have the DataSet, you could map each row into a custom class where you can add additional properties. Then use an ObservableCollection of your custom class and bind the DataGrid to this. – Lee O. Jun 20 '14 at 12:20
  • I really thank you for your help, Lee O., but I have to say I'm pretty new in WPF, and I never used anything like that. Would you mind to provide me a piece of code about that please ? I'm already checking for multibinding and the IMultiValueConverter but I'm afraid I won't find anything useful before I get it. – Adrana Jun 20 '14 at 12:21
  • I can't because my DataSet can contain more than 1000 rows, and it takes too much time to execute the query, then to add each result in a class, etc. Plus, I use this DataSet for a lot of other things, and I can't re-code all of that, I've a deadline, and I already spent a lot of time to find out how to bind everything in my grid and some more. But, I use OC of custom classes in my grid too. – Adrana Jun 20 '14 at 12:24
  • Ah...you are looking to serve up a Squirrel Burger http://benscheirman.com/2007/10/dont-make-squirrel-burgers/ – Lee O. Jun 20 '14 at 12:30
  • Hahaha ! I didn't know that ! But actually you're wrong, the deadline I'm talking about is just the end of my internship, my boss is pretty cool with me. It's just that I started to learn WPF few months ago, and I'm slowing down because of this kind of "bugs" everytime I try to make it better than it's supposed to do in WPF. Unfortunately, I don't have a lot of time to learn WPF optimization, see ? – Adrana Jun 20 '14 at 12:36

1 Answers1

0

So, as Lee O. kindly said, I've first decided to alter my DataSet by adding a new column and some data inside. The problem was that I couldn't find any way to bind successfully on this second column in my designer code.

Anyway, I knew it wasn't the best way because I kind of prevented myself to modify something big to avoid big problems in my code and some other reasons, so I spent out a whole day to make it work better. I didn't think it could have taken so much time to modify it, but it finally worked.

The solution is to create (or alter in my case) a class which represents one row in your DataGrid, with as many properties as you need, including every columns you may want to have. Then, create an ObservableCollection (I really love this type of list, very useful and easy to use / update) in your ViewModel.

Finally, bind your column to your property in your class in your MainWindow like that :

// new ViewModel() + ObservableCollection<Class>
this.gridCameras.ItemsSource = viewModel.OCCameras;
this.Total.Binding = new Binding("Total");

If it can help someone too, I found something to bind correctly this class to a ComboBox in your DataGrid, which is a bit more complicated, here and here as I suppose that your ComboBox should be written like that (don't forget the x:Name property used in the foreach loop) :

<DataGridTemplateColumn Header="Fps" Width="80" x:Name="Fps">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox x:Name="cbFps"
                      Foreground="Black"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I strongly suggest you to add an Index property in your class, since I use that to identify the object in my ObservableCollection when I edit a cell / row and some other things. It's much better than to loop on your list until you find the element everytime you'd need it.

Hope it helps and feel free to ask any question you may have. I don't say I used the best way of the world, but it works for me and that's what I wanted.

Thanks again for your tips Lee O.

Community
  • 1
  • 1
Adrana
  • 79
  • 11
  • This is some nice progress. I think your next step should be to learn how to do the stuff you are doing in the code behind in the xaml instead. I'm glad you were able to work your way through this! – Lee O. Jun 24 '14 at 03:00
  • Yay thank you ! Actually because of my C# experience I prefered to start WPF by using code behind more than Xaml. Not the best way, pretty hard, but very instructive. – Adrana Jun 24 '14 at 06:52