2013-05-26 1 views
2

Есть ли способ на C# WinForms добавлять кнопки только в некоторые из ячеек, чтобы они (кнопки) были частью ячеек? И добавьте обработчик для этих кнопок. Это необходимо для того, чтобы значения для конкретной ячейки были вставлены в другую форму. Но он не должен делать все ячейки в таблице. Как на картинке.Добавить кнопки в некоторые ячейки в datagridView

already added buttons http://i.snag.gy/vpD9Q.jpg

+0

Будет ли это * все ячейки в данном столбце *? Если да, то что дает googling * buttoncolumn *? –

+1

Если бы это было так просто ... Нет, только в некоторых камерах. – streamdown

+0

Не может ответить тогда. Но +1 и вернусь, чтобы прочитать ответы, если это можно сделать, я хочу знать, как это сделать! –

ответ

2

Проводка это как ответ, так как OP просил его:

Это мой WPF взять на себя, что:

<Window x:Class="MiscSamples.DataGridCustomCells" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:MiscSamples" 
     Title="DataGridCustomCells" Height="300" Width="300"> 
    <Window.Resources> 
     <BooleanToVisibilityConverter x:Key="BoolToVisibiltyConverter"/> 
     <Style TargetType="DataGridCell" x:Key="ButtonCell"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type DataGridCell}"> 
         <!-- ControlTemplate obtained with Expression Blend --> 
         <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
           Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> 
          <Grid> 
           <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
           <Button Height="16" Width="16" VerticalAlignment="Top" HorizontalAlignment="Right" 
             Visibility="{Binding (local:DataGridParameters.ShowButton), 
                  RelativeSource={RelativeSource TemplatedParent}, 
                  Converter={StaticResource BoolToVisibiltyConverter}}" 
             Command="{Binding CellButtonCommand, RelativeSource={RelativeSource AncestorType=Window}}" 
             CommandParameter="{Binding (local:DataGridParameters.ButtonValue), RelativeSource={RelativeSource TemplatedParent}}"/> 
          </Grid> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources> 


    <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Binding="{Binding LastName}"> 
       <DataGridTextColumn.CellStyle> 
        <Style TargetType="DataGridCell" BasedOn="{StaticResource ButtonCell}"> 
         <Setter Property="local:DataGridParameters.ShowButton" Value="{Binding DataContext.ShowButtonOnLastName, RelativeSource={RelativeSource Self}}"/> 
         <Setter Property="local:DataGridParameters.ButtonValue" Value="{Binding DataContext.LastName, RelativeSource={RelativeSource Self}}"/> 
        </Style> 
       </DataGridTextColumn.CellStyle>  
      </DataGridTextColumn> 

      <DataGridTextColumn Binding="{Binding FirstName}"> 
       <DataGridTextColumn.CellStyle> 
        <Style TargetType="DataGridCell" BasedOn="{StaticResource ButtonCell}"> 
         <Setter Property="local:DataGridParameters.ShowButton" Value="{Binding DataContext.ShowButtonOnFirstName, RelativeSource={RelativeSource Self}}"/> 
         <Setter Property="local:DataGridParameters.ButtonValue" Value="{Binding DataContext.FirstName, RelativeSource={RelativeSource Self}}"/> 
        </Style> 
       </DataGridTextColumn.CellStyle> 
      </DataGridTextColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
</Window> 

Код Behind:

public partial class DataGridCustomCells : Window 
    { 
     public ICommand CellButtonCommand { get; set; } 

     public DataGridCustomCells() 
     { 
      CellButtonCommand = new Command<object>(OnCellCommandExecuted){IsEnabled = true}; 

      InitializeComponent(); 

      DataContext = new List<DataGridSampleData> 
       { 
        new DataGridSampleData() {LastName = "Simpson", FirstName = "Homer", ShowButtonOnFirstName = true}, 
        new DataGridSampleData() {LastName = "Szyslak", FirstName = "Moe", ShowButtonOnLastName = true}, 
        new DataGridSampleData() {LastName = "Gumble", FirstName = "Barney", ShowButtonOnFirstName = true}, 
        new DataGridSampleData() {LastName = "Burns", FirstName = "Montgomery", ShowButtonOnLastName = true}, 
       }; 
     } 

     private void OnCellCommandExecuted(object parameter) 
     { 
      MessageBox.Show("Command Executed: " + parameter); 
     } 
    } 

Sample Класс данных:

public class DataGridSampleData //TODO: Implement INotifyPropertyChanged 
{ 
    public string LastName { get; set; } 

    public string FirstName { get; set; } 

    public bool ShowButtonOnFirstName { get; set; } 

    public bool ShowButtonOnLastName { get; set; } 
} 

Вспомогательные классы:

public static class DataGridParameters 
{ 
    public static readonly DependencyProperty ShowButtonProperty = DependencyProperty.RegisterAttached("ShowButton", typeof(bool), typeof(DataGridParameters)); 

    public static void SetShowButton(DependencyObject obj, bool value) 
    { 
     obj.SetValue(ShowButtonProperty, value); 
    } 

    public static bool GetShowButton(DependencyObject obj) 
    { 
     return (bool) obj.GetValue(ShowButtonProperty); 
    } 

    public static readonly DependencyProperty ButtonValueProperty = DependencyProperty.RegisterAttached("ButtonValue", typeof(object), typeof(DataGridParameters)); 

    public static void SetButtonValue(DependencyObject obj, object value) 
    { 
     obj.SetValue(ButtonValueProperty, value); 
    } 

    public static object GetButtonValue(DependencyObject obj) 
    { 
     return obj.GetValue(ButtonValueProperty); 
    } 
} 

Generic основной DelegateCommand:

//Dead-simple implementation of ICommand 
    //Serves as an abstraction of Actions performed by the user via interaction with the UI (for instance, Button Click) 
    public class Command<T>: ICommand 
    { 
     public Action<T> Action { get; set; } 

     public void Execute(object parameter) 
     { 
      if (Action != null && parameter is T) 
       Action((T)parameter); 
     } 

     public bool CanExecute(object parameter) 
     { 
      return IsEnabled; 
     } 

     private bool _isEnabled; 
     public bool IsEnabled 
     { 
      get { return _isEnabled; } 
      set 
      { 
       _isEnabled = value; 
       if (CanExecuteChanged != null) 
        CanExecuteChanged(this, EventArgs.Empty); 
      } 
     } 

     public event EventHandler CanExecuteChanged; 

     public Command(Action<T> action) 
     { 
      Action = action; 
     } 
    } 

Результат:

enter image description here

  • Обратите внимание, что я использую Attached Properties, чтобы включить дополнительное поведение в существующих DataGridCell s.
  • Кроме того, я использую DelegateCommand, чтобы эти кнопки были перенаправлены на одну и ту же базовую логику.
  • В моем примере нет ни одной строки кода, которая касается любого элемента пользовательского интерфейса. Все выполняется с помощью DataBinding. Вот как вы код в WPF.
  • Это очень простой и элементарный пример. Вы можете создать гораздо более масштабируемое решение, указав RowViewModel<TEntity>, где каждое значение ячейки обернуто в CellViewModel<TValue>, которое определяет функциональность кнопки и показывает ли она кнопку и еще что-то еще.
  • Нет «владельца ничья», нет P/Invoke, нет ужасных кодовых хаков.
  • WPF Скалы. Просто скопируйте мой код в File -> New Project -> WPF Application и посмотрите результаты сами.
+0

Благодарим вас за расширенный ответ. – streamdown