WPF: добавление столбца кнопки в сетку данных - PullRequest
3 голосов
/ 18 ноября 2009

Привет, как мне программно создать столбец Button для Datagrid. Я хочу сделать это с помощью кода в файле codebehind.

Также я хочу выборочно включить или отключить эту кнопку на основе записи (если статус открыт, то включите его, иначе отключите эту кнопку). Здесь Status - это столбец в источнике данных.

Спасибо, Аби

Ответы [ 2 ]

5 голосов
/ 03 февраля 2011

Ответ, связанный с помощью viky, обобщает идею добавления столбца кнопки из источника. Я собрал короткий пример, который также показывает вторую часть вашего вопроса, а именно, как включить / отключить кнопку на основе данных в сетке. Я использовал DataGrid в 4.0, но инструментарий с 3.5 также должен быть в порядке.

Сначала я добавляю один столбец с именем из XAML. Это не обязательно, но просто показывает, что вы можете сделать комбинацию дополнений XAML и C # в таблицу. Обратите внимание, что я называю сетку здесь, чтобы у меня был способ ссылаться на нее в частичном классе C #.

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Data Grid Populated in XAML and C#">
    <Grid>
        <DataGrid x:Name="_gridControl" IsReadOnly="True" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Width="*" Binding="{Binding Name}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Теперь я делаю две вещи в коде. Помимо добавления столбца кнопки и элементов данных (которые имеют имя и статус), я создаю класс Converter, который будет возвращать true, если значение равно «Open», и false в противном случае. Затем при настройке привязки (в отличие от значения) я также добавляю свой конвертер, чтобы при создании и связывании контейнеров ItemsControl для моих элементов отображаемая кнопка имела состояние IsEnabled, связанное с полем «Состояние» моего элемента.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var buttonTemplate = new FrameworkElementFactory(typeof(Button));
        buttonTemplate.SetBinding(Button.ContentProperty, new Binding("Name"));
        buttonTemplate.SetBinding(Button.IsEnabledProperty, new Binding("Status")
        {
            Converter = new StatusToEnabledConverter()
        });
        buttonTemplate.AddHandler(
            Button.ClickEvent, 
            new RoutedEventHandler((o, e) => MessageBox.Show("hi"))
        );
        this._gridControl.Columns.Add(
            new DataGridTemplateColumn()
            {
                Header = "Close Button",
                CellTemplate = new DataTemplate() { VisualTree = buttonTemplate }
            }
        );

        this._gridControl.ItemsSource = new object[]
        {
            new { Name = "First Item", Status = "Open" },
            new { Name = "Second Item", Status = "Open" },
            new { Name = "Third Item", Status = "Closed" },
            new { Name = "Fourth Item", Status = "Closed" },
            new { Name = "Fifth Item", Status = "Open" }
        };
    }
}

public class StatusToEnabledConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        return "Open".Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }
}

И еще одно важное замечание: я модифицирую DataGrid из C # только после вызова InitializeComponent. Для элемента управления содержимым WPF, в котором есть части XAML и C #, это важно, поскольку построение объекта, выполняемое с помощью XAML, должно быть завершено до того, как вы начнете изменять объекты, определенные в XAML.

Надеюсь, это поможет!

1 голос
/ 03 декабря 2018

XAML:

<DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Click="Details">Details</Button>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>

Код позади

       private IEnumerable<DataGridRow> GetDataGridRowsForButtons(DataGrid grid)
    { //IQueryable 
        var itemsSource = grid.ItemsSource as IEnumerable;
        if (null == itemsSource) yield return null;
        foreach (var item in itemsSource)
        {
            var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
            if (null != row & row.IsSelected) yield return row;
        }
    }

    void Details(object sender, RoutedEventArgs e)
    {

        for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
            if (vis is DataGridRow)
            {
               // var row = (DataGrid)vis;

                var rows = GetDataGridRowsForButtons(dgv_Students);
                string id;
                foreach (DataGridRow dr in rows)
                {
                    id = (dr.Item as tbl_student).Identification_code;
                    MessageBox.Show(id);
                }
                break;
            }
    }

После нажатия на кнопку вам возвращается идентификатор этой строки, и вы можете использовать его в качестве имени кнопки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...