2014-10-09 205 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