.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与网格同步?
当我有一个可编辑的网格时,或者我更改网格样式以删除或减少行高亮效果。
答案 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);
}
}
}