Ответ, связанный с помощью 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.
Надеюсь, это поможет!