我在ResourceDictionary中定义了两种不同的样式,如下所示:
<Style TargetType="{x:Type Button}" x:Key="EditButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" Background="{StaticResource BrushBlueSelector}" Padding="5,2" SnapsToDevicePixels="true" CornerRadius="3">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Color="Turquoise" BlurRadius="8" />
</Border.Effect>
<Path x:Name="buttonSymbol" Data="M0,44.439791L18.98951,54.569246 0.47998798,62.66881z M17.428029,12.359973L36.955557,23.568769 21.957478,49.686174 20.847757,46.346189 15.11851,45.756407 14.138656,42.166935 8.5292659,41.966761 6.9493899,38.037481 2.4399572,38.477377z M26.812517,0.0009765625C27.350616,-0.012230873,27.875986,0.10826397,28.348372,0.3782568L42.175028,8.3180408C43.85462,9.2780154,44.234529,11.777948,43.02482,13.89789L41.375219,16.767812 21.460039,5.3381228 23.10964,2.4582005C23.979116,0.941679,25.437378,0.034730911,26.812517,0.0009765625z"
Stretch="Uniform" Fill="#FFFFFFFF" Width="24" Height="24" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushOrangeSelector}"/>
<Setter TargetName="Border" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Orange" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushHeaderBackground}"/>
<Setter TargetName="Border" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Gray" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Gray"/>
<Setter TargetName="Border" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Gray" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Tag" Value="EditButton" />
<Setter Property="Margin" Value="3" />
<Setter Property="Focusable" Value="False" />
</Style>
<Style TargetType="{x:Type Button}" x:Key="SaveButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" Background="{StaticResource BrushBlueSelector}" Padding="5,2" SnapsToDevicePixels="true" CornerRadius="3">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Color="Turquoise" BlurRadius="2" />
</Border.Effect>
<Path x:Name="buttonSymbol" Data="M8.1099597,36.94997L8.1099597,41.793968 39.213959,41.793968 39.213959,36.94997z M12.42,0.049999889L18.4,0.049999889 18.4,12.252 12.42,12.252z M0,0L7.9001866,0 7.9001866,14.64218 39.210766,14.64218 39.210766,0 47.401001,0 47.401001,47.917 0,47.917z"
Stretch="Uniform" Fill="#FFFFFFFF" Width="24" Height="24" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="Green"/>
<Setter TargetName="Border" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Green" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushHeaderBackground}"/>
<Setter TargetName="Border" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Gray" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Tag" Value="SaveButton" />
<Setter Property="Margin" Value="3" />
<Setter Property="Focusable" Value="False" />
</Style>
我在dataGrid中有一个编辑按钮,如下所示:
<DataGrid Grid.Column="1" Margin="50" ItemsSource="{Binding Names}"
CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}" Width="*" Header="Names"/>
<DataGridTemplateColumn Header="Edit">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Style="{StaticResource EditButton}" Click="EditButton_InsideDataGrid_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
这是点击事件:
private void EditButton_InsideDataGrid_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
string tagValue = String.Empty;
if (button != null)
{
tagValue = button.Tag.ToString();
if (tagValue == "EditButton")
{
button.Style = (Style)Application.Current.Resources["SaveButton"];
}
else if (tagValue == "SaveButton")
{
button.Style = (Style)Application.Current.Resources["EditButton"];
}
}
}
现在,它运作正常。我可以看到:
Initially : Style is EditButton.
Click 1st time : Style is SaveButton.
Click 2nd time : Style is EditButton.
Click 3rd time : Style is SaveButton.
Click 4th time : Style is EditButton.
Click 5th time : Style is SaveButton.
......
......
......
现在,当我在editButton的Click事件中添加下面提到的代码时:
int colIndex = 0;
int rowIndex = 0;
DependencyObject dep = (DependencyObject)e.OriginalSource;
while (dep != null && !(dep is DataGridCell))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
if (dep is DataGridCell)
{
colIndex = ((DataGridCell)dep).Column.DisplayIndex;
while (dep != null && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
DataGridRow row = (DataGridRow)dep;
rowIndex = FindRowIndex(row);
}
while (dep != null && !(dep is DataGrid))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGrid dg = (DataGrid)dep;
for (int column = 0; column < colIndex; column++)
{
if (!(dg.Columns[column].IsReadOnly))
{
DataGridCell cell = GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column]));
//cell.IsEditing = true;
}
}
dg.BeginEdit();
}
public DataGridCell GetDataGridCell(DataGridCellInfo cellInfo)
{
var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
if (cellContent != null)
return (DataGridCell)cellContent.Parent;
return null;
}
private int FindRowIndex(DataGridRow row)
{
DataGrid dataGrid = ItemsControl.ItemsControlFromItemContainer(row) as DataGrid;
int index = dataGrid.ItemContainerGenerator.IndexFromContainer(row);
return index;
}
现在,我的结果是:
Initially : Style is EditButton.
Click 1st time : Style is EditButton.
Click 2nd time : Style is SaveButton.
Click 3rd time : Style is EditButton.
Click 4th time : Style is SaveButton.
Click 5th time : Style is EditButton.
......
......
......
以下是我重现同样问题的示例项目:
https://drive.google.com/file/d/0B5WyqSALui0beVJXTG5yWTZwZm8/view?usp=sharing
更新
@Yoyo建议的新样本:https://drive.google.com/file/d/0B5WyqSALui0bUGxRRklDOUpKRms/view?usp=sharing
我试图成功关注@ Yoyo的说明。但问题仍然存在。
答案 0 :(得分:1)
以下是我提供解决问题的方法
我重写按钮的样式
<Style TargetType="{x:Type Button}"
x:Key="EditSaveStyle">
<Style.Resources>
<Brush x:Key="BrushHeaderBackground">#FF2A2A2A</Brush>
<Brush x:Key="BrushBlueSelector">#FF0094FF</Brush>
<Brush x:Key="BrushOrangeSelector">#FFFF6A00</Brush>
</Style.Resources>
<Setter Property="Margin"
Value="3" />
<Setter Property="Focusable"
Value="False" />
<Setter Property="Width"
Value="32" />
<Setter Property="Height"
Value="32" />
<Setter Property="Background"
Value="{StaticResource BrushOrangeSelector}" />
<Setter Property="Content">
<Setter.Value>
<StreamGeometry>
M0,44.439791L18.98951,54.569246 0.47998798,62.66881z M17.428029,12.359973L36.955557,23.568769 21.957478,49.686174 20.847757,46.346189 15.11851,45.756407 14.138656,42.166935 8.5292659,41.966761 6.9493899,38.037481 2.4399572,38.477377z M26.812517,0.0009765625C27.350616,-0.012230873,27.875986,0.10826397,28.348372,0.3782568L42.175028,8.3180408C43.85462,9.2780154,44.234529,11.777948,43.02482,13.89789L41.375219,16.767812 21.460039,5.3381228 23.10964,2.4582005C23.979116,0.941679,25.437378,0.034730911,26.812517,0.0009765625z
</StreamGeometry>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border"
Background="{StaticResource BrushBlueSelector}"
Padding="5,2"
SnapsToDevicePixels="true"
CornerRadius="3">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Turquoise"
BlurRadius="8" />
</Border.Effect>
<Path x:Name="buttonSymbol"
Data="{TemplateBinding Content}"
Stretch="Uniform"
Fill="#FFFFFFFF"
RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1"
ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="Border"
Property="Background"
Value="{Binding Background,RelativeSource={RelativeSource TemplatedParent}}" />
<Setter TargetName="Border"
Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0"
Color="{Binding Background.Color,RelativeSource={RelativeSource TemplatedParent}}"
BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<Setter TargetName="Border"
Property="Background"
Value="{StaticResource BrushHeaderBackground}" />
<Setter TargetName="Border"
Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0"
Color="Gray"
BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter TargetName="Border"
Property="Background"
Value="Gray" />
<Setter TargetName="Border"
Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0"
Color="Gray"
BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditing,RelativeSource={RelativeSource AncestorType=DataGridRow}}"
Value="true">
<Setter Property="Content">
<Setter.Value>
<StreamGeometry>M8.1099597,36.94997L8.1099597,41.793968 39.213959,41.793968 39.213959,36.94997z M12.42,0.049999889L18.4,0.049999889 18.4,12.252 12.42,12.252z M0,0L7.9001866,0 7.9001866,14.64218 39.210766,14.64218 39.210766,0 47.401001,0 47.401001,47.917 0,47.917z</StreamGeometry>
</Setter.Value>
</Setter>
<Setter Property="Background"
Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
DataGridRow.IsEditing
这里是主窗口中的代码重写
private void EditButton_InsideDataGrid_Click(object sender, RoutedEventArgs e)
{
int colIndex = 0;
int rowIndex = 0;
DependencyObject dep = (DependencyObject)e.OriginalSource;
while (dep != null && !(dep is DataGridCell))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGridRow row = null;
if (dep is DataGridCell)
{
colIndex = ((DataGridCell)dep).Column.DisplayIndex;
while (dep != null && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
row = (DataGridRow)dep;
rowIndex = FindRowIndex(row);
}
while (dep != null && !(dep is DataGrid))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGrid dg = (DataGrid)dep;
if (row != null)
{
if (row.IsEditing)
dg.CommitEdit(DataGridEditingUnit.Row, true);
else
{
dg.CurrentCell = new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[0]);
dg.BeginEdit();
}
}
}
我做了一些调整来编辑并保存一行。
最后是数据网格
<DataGrid Grid.Column="1" Margin="50" ItemsSource="{Binding Names}"
CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=.}" Width="*" Header="Names"/>
<DataGridTemplateColumn Header="Edit" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Click="EditButton_InsideDataGrid_Click"
Style="{StaticResource EditSaveStyle}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
我在标准按钮上使用了样式EditSaveStyle
使用这种方法,您可能不需要继承和创建自己的按钮来切换样式等。如果您期待自定义更多,可能会引入附加属性。
这是一个工作样本ChangingStylesAtRuntime.zip
请注意,如果数据未正确绑定,或dg.CommitEdit
未设置为未绑定/只读列,则IsReadOnly="True"
可能会失败
答案 1 :(得分:0)
考虑使用DataTemplateSelector类。
此类提供了一种基于数据对象和数据绑定元素选择DataTemplate的方法。
<强> XAML:强>
<Window.Resources>
...
<local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>
...
</Window.Resources>
...
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
HorizontalContentAlignment="Stretch"/>
<强>类别:强>
public class TaskListDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null && item is Task)
{
Task taskitem = item as Task;
if (taskitem.Priority == 1)
return
element.FindResource("importantTaskTemplate") as DataTemplate;
else
return
element.FindResource("myTaskTemplate") as DataTemplate;
}
return null;
}
}