DataGrid SelectionUnit = Cell禁用对所选行的所有支持?

时间:2012-02-28 20:17:01

标签: wpf datagrid

.Net 4 WPF DataGrid C#MMVM

当DataGrid SelectionUnit为完整行时,wpf数据绑定和collectionview会通过视图的currentitem属性让我知道viewmodel中主动选择的项目是什么。这对于只读网格很有用,选择模式设置为fullrow。

现在我有一个可编辑的网格。因此,我设置了SelectionUnit = Cell,以便更容易找到一个单元格。现在,网格突然不再具有跟踪选择项目的能力。设置为单元格模式时,我甚至无法设置SelectedItem。所以现在viewmodel总是认为它在第一行。我可以在网格中处理SelectedCellsChanged以找出我在哪一行,我只是无法让视图模型知道,因为网格的SelectedItem不能再被设置了!

我不明白为什么在单元格选择模式下网格仍然没有SelectedItem。

没有硬编码到我的网格中以将ItemSource转换为我的collectionview以从SelectedCellsChanged事件调用MoveCurrentTo,是否还有其他MVVM真正的方法来保持视图的CurrentItem与网格同步?

当我有一个可编辑的网格时,或者我更改网格样式以删除或减少行高亮效果。

3 个答案:

答案 0 :(得分:6)

我正在寻找同样的问题并找到了一个简单的解决方案

要访问设置为SelectionUnit Cell的行,您必须这样做:

DataGridXX.SelectedCells[0].item

仅当您一次只能选择一个单元格(而不是在扩展模式下)时,它才有效。

答案 1 :(得分:0)

我也有类似的问题,所以这里是我使用的样式(从网络复制)。 因此,您从http://datagridthemesfromsl.codeplex.com/复制WhistlerBlue主题并进行以下修改。希望这会有所帮助。

<!--Cell-->
<Style x:Key='CellStyle' TargetType="{x:Type controls:DataGridCell}" >
    <Setter Property="Foreground" Value="{StaticResource ThemeForegroundBrush}" />
    <Setter Property="Height" Value="Auto" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Cursor" Value="Arrow" />
    <Setter Property="BorderThickness" Value="1" />
    <!--Padding hack-->
    <Setter Property="Padding" Value="2 5 2 5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:DataGridCell}">
                <Grid x:Name="Root" Background="Transparent">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Rectangle x:Name="FocusVisual" Margin="0,-2,0,0" 
                               Stroke="White"  Fill="White" 
                               Opacity="0" IsHitTestVisible="false"/>
                    <ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" 
                                      ContentTemplate="{TemplateBinding ContentTemplate}" Cursor="{TemplateBinding Cursor}"/>
                    <Rectangle x:Name="RightGridLine" VerticalAlignment="Stretch" Width="1" Grid.Column="1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

</Style>

<!-- DataGridRow -->
<Style x:Key='RowStyle' TargetType="{x:Type controls:DataGridRow}">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:DataGridRow}">
                <Border x:Name="DGR_Border"
              Background="{TemplateBinding Background}"
              BorderBrush="{TemplateBinding BorderBrush}"
              BorderThickness="{TemplateBinding BorderThickness}"
              SnapsToDevicePixels="True">
                    <primitives:SelectiveScrollingGrid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height='Auto' />
                        </Grid.RowDefinitions>
                        <Rectangle x:Name="Selected" Margin="0" Grid.RowSpan="2" Grid.ColumnSpan="2" 
                               Fill="{StaticResource BtnOverFill}" Stroke="{StaticResource selectedStroke}" 
                               Opacity="0"/>
                        <Rectangle x:Name="SelectedHighlight" Margin="1" Grid.RowSpan="2" Grid.ColumnSpan="2" 
                               Stroke="#A0FFFFFF" 
                               Opacity="0"/>
                        <primitives:DataGridRowHeader Grid.RowSpan="2"
                                                    primitives:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"                                       
                                                    Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:DataGrid}}, 
                            Path=HeadersVisibility, 
                            Converter={x:Static controls:DataGrid.HeadersVisibilityConverter},
                            ConverterParameter={x:Static controls:DataGridHeadersVisibility.Row}}"/>
                        <Rectangle x:Name="Over" Margin="0" Grid.RowSpan="2" Grid.ColumnSpan="2" 
                               Fill="{StaticResource hoverGradient}" 
                               Stroke="{StaticResource hoverStroke}" 
                               Opacity="0"/>
                        <primitives:DataGridCellsPresenter Grid.Column="1"
                                        ItemsPanel="{TemplateBinding ItemsPanel}"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        <primitives:DataGridDetailsPresenter Grid.Column="1" Grid.Row="1"
                                                           x:Name='DetailsPresenter' 
                                                           primitives:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static controls:DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static controls:SelectiveScrollingOrientation.Vertical}}"                                                                                                                         
                                                           Visibility="{TemplateBinding DetailsVisibility}"                                                               
                                                           />
                        <Rectangle Height="1" HorizontalAlignment="Stretch" 
                                   x:Name="BottomGridLine" 
                                   Fill="{StaticResource HorizontalVerticalGridLinesBrush}" 
                                   Grid.Column="1" Grid.Row="2" />
                    </primitives:SelectiveScrollingGrid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property='IsSelected' Value='True'>
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="Selected" Storyboard.TargetProperty="Opacity" To="0.84"/>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="SelectedHighlight" Storyboard.TargetProperty="Opacity" To="1"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="Selected" Storyboard.TargetProperty="Opacity" To="0"/>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="SelectedHighlight" Storyboard.TargetProperty="Opacity" To="0"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                        <!--<Setter Property="DetailsVisibility" Value="Visible" />-->
                    </Trigger>
                    <MultiTrigger >
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True" />
                            <Condition Property="IsSelected" Value="False" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="Over" Storyboard.TargetProperty="Opacity" To="0.73"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </MultiTrigger.EnterActions>
                        <MultiTrigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="Over" Storyboard.TargetProperty="Opacity" To="0"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </MultiTrigger.ExitActions>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True" />
                            <Condition Property="IsFocused" Value="False" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="Selected" Storyboard.TargetProperty="Opacity" To="0.84"/>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="SelectedHighlight" Storyboard.TargetProperty="Opacity" To="1"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </MultiTrigger.EnterActions>
                        <MultiTrigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="Selected" Storyboard.TargetProperty="Opacity" To="0"/>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="SelectedHighlight" Storyboard.TargetProperty="Opacity" To="0"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </MultiTrigger.ExitActions>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

答案 2 :(得分:0)

我使用附加属性在MSDN上找到了一个很好的解决方案:

<DataGrid ItemsSource="{Binding}" IsReadOnly="True" SelectionUnit="Cell">
  <DataGrid.CellStyle>
    <Style TargetType="{x:Type DataGridCell}">
      <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
          <Setter Property="local:DataGridAttachedProperties.IsCellSelected" Value="True"/>
        </Trigger>
        <Trigger Property="IsSelected" Value="False">
          <Setter Property="local:DataGridAttachedProperties.IsCellSelected" Value="False"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </DataGrid.CellStyle>
  <DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
      <Style.Triggers>
        <Trigger Property="local:DataGridAttachedProperties.IsCellSelected" Value="True">
          <Setter Property="BorderThickness" Value="2"/>
          <Setter Property="BorderBrush" Value="Red"/>
          <Setter Property="Background" Value="Yellow"/>
          <Setter Property="Opacity" Value="0.7"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </DataGrid.ItemContainerStyle>
</DataGrid>

还有C#:

public class DataGridAttachedProperties
{
    public static bool GetIsCellSelected(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCellSelectedProperty);
    }
    public static void SetIsCellSelected(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCellSelectedProperty, value);
    }
    public static readonly DependencyProperty IsCellSelectedProperty =
        DependencyProperty.RegisterAttached("IsCellSelected", typeof(bool), typeof(DataGridAttachedProperties), new UIPropertyMetadata(false,
        (o, e) =>
        {
            if (o is DataGridCell)
            {
                DataGridRow row = VisualTreeHelperEx.FindVisualParent<DataGridRow>(o as DataGridCell);
                row.SetValue(DataGridAttachedProperties.IsCellSelectedProperty, e.NewValue);
            }
        }));
}
public class VisualTreeHelperEx
{
    public static T FindVisualParent<T>(DependencyObject child)
    where T : DependencyObject
    {
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);
        if (parentObject == null) return null;
        T parent = parentObject as T;
        if (parent != null)
        {
            return parent;
        }
        else
        {
            return FindVisualParent<T>(parentObject);
        }
    }
}