views:

190

answers:

3

I am seeing a lot of examples on how to style Selected rows in DataGrid such as this one:

http://stackoverflow.com/questions/1223280/how-can-i-set-the-color-of-a-selected-row-in-datagrid

Can i just disabled selected row styling? i don't want to have to override every single thing that selected row changes. Just don't want any visible changes. Gotta be easier way than to create templates..

or..

disable selecting rows, if that is easier.. but from browsing this forum that seems hacky as well

http://stackoverflow.com/questions/2496814/disable-selecting-in-wpf-datagrid

+1  A: 

This is relatively straightforward:

datagrid.SelectionChanged += (obj, e) =>
  Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
    datagrid.UnselectAll()));

This disables all selection on the DataGrid.

If you don't want to disable selection entirely but just hide it you'll need to modify the template.

Ray Burns
well for one i've tried that, and it still lets me select. this kind of override prevents some selections, but not all. at least visually, i can still see the row selected.
Sonic Soul
Ok, I tried it too and discovered you have to use a Dispatcher callback. The new code in my answer actually works, but it is three lines now instead of one. Is that too "hacky" for you? The reason the BeginInvoke is required is that MultiSelector's selection change handler tries to lock in the user's selection change with its own Dispatcher callback.
Ray Burns
thanks, i appreciate your help with this. but what does number of lines have to do with "hacky" code? there reason this is hacky, is because it isnt actually disabling anything, just unselecting all every time selection changes.. and using a dispatcher invoke.. how is this not a hack?
Sonic Soul
You're right: Number of lines has nothing to do with hackiness. You're also right that reversing actions is more "hacky" then disabling them (eg if you had a "DisableSelection"). Please leave the dispatcher out of it, though: Dispatcher.BeginInvoke is a standard and very important WPF feature. BeginInvoke is MY FRIEND and I won't have you calling it hacky! YOU TAKE IT BACK THIS INSTANT OR I'LL ..... :-)) [BIG GRIN] Ok, maybe it is a little hacky. Sometimes. I hope your project goes well for you.
Ray Burns
heh. i hope he isn't to sensitive :) to be honest i am not sure how safe that call to dispatcher begininvoke is and kind of reluctant to put it in my app.. trying to disguise selected style as not selected, but not having much luck with that either, because i don't seem to be able to set Foreground/Background as transparent in selected style, so as to show the original colors (which are different for every cell in the row) cant believe this thing is causing so much grief!
Sonic Soul
also, your code doesn't seem to be working for me.. (i tried it out of curiosity)
Sonic Soul
heh!!i added timer code, that calls UnselectAll every second, just for the FUN of it.. and it still doesn't clear the selection!!!!
Sonic Soul
The code I posted actually works for me, and it works completely reliably. You might try it with a plain-vanilla DataGrid with nothing but a ItemsSource and a couple of DataGridTextColumns to see if it is something you're doing or a difference between our systems. I tried this on NET Framework 3.51 SP1 with WPFToolkit Feb2010. What are you using?
Ray Burns
Dispatcher.BeginInvoke is totally safe. It introduces no threading issues whatever since it executes on the same thread. All it does is call you back at the priority you request after the last dispatcher operation has returned. I use it all the time and so do many others. You should get used to using Dispatcher.BeginInvoke if you're going to be a WPF programmer because there are lots of things you'll want it for.
Ray Burns
hmm.. correct me if im wrong but i thought BeginInvoke is the asynchronous cousin of Invoke, there by making it definitely executed on a different thread. there is no callback or thread synchronization here so i guess that shouldn't cause multi threading issues however..
Sonic Soul
You are wrong. Dispatcher has the ability to cross threads when necessary, but will only do so if you tell it to do so by selecting a Dispatcher for a different thread than you are on. When used within a UI object like this, Dispatcher.Invoke and Dispatcher.BeginInvoke simply execute the method - one synchronously, the other asynchronously. No other thread gets involved in any way, shape, or form. Glad I could clear this up for you. I can see why you were leery of using Dispatcher.BeginInvoke because of your misunderstanding of what it did.
Ray Burns
+1  A: 

figured out the XAML to get rid of selection style.. not ideal, but close enough..

<Style x:Key="CellStyle" TargetType="{x:Type DataGridCell}">
    <Setter Property="Foreground" Value="Black" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
        </Trigger>
    </Style.Triggers>
</Style>
Sonic Soul
+1  A: 

I found another way that works well for my situation. I set this style for all cells because I don't want the user to select any cells.

<Style TargetType="{x:Type DataGridCell}">
    <Setter Property="IsHitTestVisible" Value="False"/>
</Style>
Brian Ensink
very nice.. i will have to test this soon
Sonic Soul
where do you put this in the DataGrid XAML to apply it to all cells?
tyndall