DataGrid: SelectionUnit & RowDetailsVisibilityMode

Jan 6, 2009 at 2:48 PM
Hi Folks,

I currently have a datagrid with a number of datafields one of which is a DataTemplate which basically houses a button. When I click on the button I want to be able to display the RowDetailsVisibilty for the selected row (where the button lives). If I select any other cell on the row I do not want any RowDetailsVisibility at all. 

If I set the SelectionUnit to "Cell" I get the button event as expected but no RowDetailsVisibilityChanged event and when the SelectionUnit is set to Row I get both events. Is there another property or event that I can capture that will allow me to set the DetailsVisibilty for a prescribed row and collapses all others?

Coordinator
Jan 7, 2009 at 12:47 PM
Instead, you can control the DetailsVisibility per row using a style trigger.  Here is an example from a sample I'm currently building:

 

 

<Style x:Key="DefaultRowStyle" TargetType="{x:Type toolkit:DataGridRow}">
    <Setter Property="DetailsTemplate" Value="{StaticResource AnimationPropertyDataTemplate}" />
    <Setter Property="DetailsVisibility" Value="Collapsed" />
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=IsSelected}" Value="true" />
                <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="true" />
            </MultiDataTrigger.Conditions>
            <Setter Property="DetailsVisibility" Value="Visible" />
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

 

My data item has this property IsSelected which I use to trigger the DataGridRow.  I also use the DataGridRow.IsSelected as an additional condition since I allow multi-selection.  So for your scenario, when the button is clicked you can set the dataItem.IsSelected (dataItem being the item for that particular row) to true, or toggle, or whatever functionality you would like.
Jan 7, 2009 at 1:11 PM
Hi Vinsibal,

I have only been studying WPF for about 1 week so all this is really new to me. Is it possible you can show me an an example of this working?
Coordinator
Jan 13, 2009 at 1:42 AM
Here is a bit more of the implementation, hopefully this will help you solve your issue:

 

 

<toolkit:DataGrid Name="MyDataGrid" ItemsSource="{Binding Path=DataItemCollection}">
    <toolkit:DataGrid.Columns>
        <toolkit:DataGridTemplateColumn> 
            <toolkit:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox HorizontalAlignment="Center" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </toolkit:DataGridTemplateColumn.CellTemplate>
        </toolkit:DataGridTemplateColumn> 
    </toolkit:DataGrid.Columns>
</toolkit:DataGrid>

public class DataItem : INotifyPropertyChanged
{
    private bool _isSelected;
    public bool IsSelected
    {    
        get { return _isSelected; }
        set
        {
            _isSelected =
value;
            OnPropertyChanged(
"IsSelected");
         }
        }
}

 

Jan 15, 2009 at 8:10 AM
Hi Vinsibal,
I have tried this and it doesn't seem to work. This is what I have got:

<Window.Resources>
        <Style x:Key="DefaultRowStyle" TargetType="{x:Type my:DataGridRow}">
            <Setter Property="DetailsVisibility" Value="Collapsed" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                       
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="true" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="DetailsVisibility" Value="Hidden" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
   
    <Grid>
        <my:DataGrid Margin="21,12,57,50" Name="dataGrid1"
                     ItemsSource="{Binding lstHumans}"       ///this is the name of the observable collection
                       SelectionMode="Single"  SelectionUnit="Cell">

            <my:DataGrid.RowDetailsTemplate>
                <DataTemplate >
                    <TextBlock></TextBlock>
                </DataTemplate>
            </my:DataGrid.RowDetailsTemplate>
           
            <my:DataGrid.Columns>
                <my:DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <my:DataGridTemplateColumn>
                    <my:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox HorizontalAlignment="Center" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </my:DataGridTemplateColumn.CellTemplate>
                </my:DataGridTemplateColumn>

            </my:DataGrid.Columns>
        </my:DataGrid>
    </Grid>

And the Class it binds too: which is an observable collection

 

public class HumanList : ObservableCollection<Human>
    {
        public HumanList() : base() { }
    }

    public class Human: INotifyPropertyChanged
    {
        public Human(string name, int age, bool edit)
        {
            this.Age = age;
            this.Name = name;
            this.Edit = edit;
        }

        public string Name { get; set; }
        public int Age { get; set; }
        public bool Edit { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }

        private void OnPropertyChanged(string property)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

    }

 

Jan 15, 2009 at 8:21 AM
The stuff I sent you had a typo in it regarding the details visibility, but just to let you know it still doesnt work with the remaining xaml and code. Any ideas??????

<Window.Resources>
        <Style x:Key="DefaultRowStyle" TargetType="{x:Type my:DataGridRow}">
            <Setter Property="DetailsVisibility" Value="Collapsed" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                       
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="true" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="DetailsVisibility" Value="Visible" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
Coordinator
Jan 15, 2009 at 12:03 PM
You didn't set the row style on the DataGrid, e.g. RowStyle = {StaticResource DefaultRowStyle}.  Also, in your multibinding you only have a binding on the DataGridRow.IsSelected which is no different than setting DetailsVisibitlity to VisibleWhenSelected.
Jan 15, 2009 at 12:26 PM
I have now added the Rowstyle to the datagrid and modifeid the resource to

<Window.Resources>
        <Style x:Key="DefaultRowStyle" TargetType="{x:Type my:DataGridRow}">
            <Setter Property="DetailsVisibility" Value="Collapsed" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="true" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="DetailsVisibility" Value="Visible" />
                </MultiDataTrigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="false" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="DetailsVisibility" Value="Collapsed" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

but still does not work. I think I have interpreted correctly what you said and applied to teh resource
Jan 19, 2009 at 8:44 AM
Hi Vinsibal,

Can you assist me with this I just cannot seem to get this to work? If you can get it to work then I must be doing something wrong but just cannot see it
Coordinator
Jan 21, 2009 at 12:54 PM
Take a look at the sample on this blog post, http://blogs.msdn.com/vinsibal/archive/2009/01/21/exploring-mvvm-grouping-with-the-datagrid.aspx