2014-10-09 164 views
1

我已经在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 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

我试图成功地关注@悠悠的指示。但问题仍然存在。

+1

这不是很常见的方式如何dg.CommitEdit可能会失败解决这种类型的行为。这是非常丑陋而不是简单的解决方案。尝试创建自定义按钮并创建依赖项属性,例如模式=编辑/保存,在一些触发器或故事板中,您只能更改所需的值。不是整个按钮的样式。 – 2014-10-09 12:15:53

+0

@YoYo我成功实现了你的想法。但问题仍然存在。以下是新示例:https://drive.google.com/file/d/0B5WyqSALui0bUGxRRklDOUpKRms/view?usp=sharing – Vishal 2014-10-09 13:45:34

回答

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

这里的重写代码在主窗口中.sd

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

注意,如果数据没有正确绑定或IsReadOnly="True"没有被设置为未绑定/只读列

+0

谢谢。我试图在我的示例项目以及我的真实项目中实现您的答案。我在两个项目中都有所不同。在我的示例项目中,一切运行良好。但在我的真实项目中,我看不到像按钮上的铅笔或软盘等任何图标。你能告诉我这个问题吗? – Vishal 2014-10-10 09:51:47

+0

@Vishal,你还有失踪的图标问题吗?丢失图标可能是由于按钮本身设置的内容造成的,因为样式不能覆盖本地值。所以请删除按钮上的任何内容,例如'。如果问题仍然存在,我可能需要查看实际的实施情况。 – pushpraj 2014-10-11 04:51:19

+0

非常感谢。我从来没有看过Button的内容。现在它工作正常。 – Vishal 2014-10-11 06:25:36

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; 
    } 
} 
+0

正如您在此处所述,DataTemplateSelector提供了一种基于数据对象和数据对象选择DataTemplate的方法,绑定的集合。但是,如果您回顾我的问题,我不想更改DataGridRows的模板。我只想更改dataGrid中按钮的ControlTemplate。当按钮初始化时,它获得编辑按钮的ControlTemplate。当用户点击它时,该按钮的ControlTemplate应该切换到保存按钮。再次单击编辑按钮等.......感谢您的尝试。 – Vishal 2014-10-09 14:57:34