积极答复者
使用mvvm在DataGrid的DataGridTemplateColumn.HeaderTemplate在使用Command绑定不成功

问题
-
<Window.DataContext> <ViewModels:MyViewModel/> </Window.DataContext> <DataGrid ItemsSource="{Binding Path = MyModels}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0,0,0,68" Name="dg" VerticalAlignment="Stretch"> <DataGrid.Columns> <DataGridTemplateColumn > <DataGridTemplateColumn.HeaderTemplate> <DataTemplate> <CheckBox x:Name="ckbSelectedAll" Command="{Binding ShowtCmd}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.HeaderTemplate> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox x:Name="ckbSelectedAll" IsChecked="{Binding IsCheck}" Command="{Binding ShowtCmd}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="id"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Id}"></TextBlock> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="button"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Name="bt" Content="{Binding Name}" Command="{Binding ShowtCmd}"></Button> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
我在MyViewModel里面也放了一个ShowtCmd 在数据类里面也有ShowtCmd 方法名称一样的 下面的2个都绑定成功了 请问HeaderTemplate里面要如何绑定
答案
-
那么不用StaticResource, 直接绑定到DataGrid上面试试吧。
<Button Content="Head" Command="{Binding ElementName=dg, Path=DataContext.cmd}"/> ——————————————————————————分割线—————————————————————————— <Window.Resources> <loc:ViewModel x:Key="vm"/> </Window.Resources> <StackPanel DataContext="{Binding Source={StaticResource vm}}"> <DataGrid Name="dg" ItemsSource="{Binding View}" AutoGenerateColumns="False" Tag="123"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding col1}" > <DataGridTextColumn.HeaderTemplate> <DataTemplate> <Button Content="Head" Command="{Binding ElementName=dg, Path=DataContext.cmd}"/> </DataTemplate> </DataGridTextColumn.HeaderTemplate> </DataGridTextColumn> </DataGrid.Columns> </DataGrid> <Label Content="{Binding Prop2}"/> </StackPanel>
谢谢。
Yoyo Jiang[MSFT]
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- 已标记为答案 huanghy 2013年6月5日 2:14
全部回复
-
你好!
可能是由于Header部分没有DataContext.
请把Command绑定到一个static resource上面试试。
可以参考下面的代码:
<Window x:Class="CommandingBindingProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:loc="clr-namespace:CommandingBindingProject" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <loc:ViewModel x:Key="vm"/> </Window.Resources> <StackPanel DataContext="{Binding Source={StaticResource vm}}"> <DataGrid Name="dg" ItemsSource="{Binding View}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding col1}" SortMemberPath=""> <DataGridTextColumn.HeaderTemplate> <DataTemplate> <Button Content="Head" Command="{Binding Source={StaticResource vm}, Path=cmd}"/> </DataTemplate> </DataGridTextColumn.HeaderTemplate> </DataGridTextColumn> </DataGrid.Columns> </DataGrid> <Label Content="{Binding Prop2}"/> </StackPanel> </Window>
public class ViewModel : INotifyPropertyChanged { CollectionViewSource cvs = new CollectionViewSource(); public ICollectionView View { get { if (cvs.View == null) { DataTable dt = new DataTable(); var _with1 = dt; var _with2 = _with1.Columns; var _with3 = _with2.Add("ID", typeof(int)); _with3.AutoIncrement = true; _with3.AutoIncrementSeed = 1; _with3.AutoIncrementStep = 1; _with2.Add("col1", typeof(string)); for (int i = 1; i <= 10; i++) { dynamic r = _with1.NewRow(); r[1] = string.Format("Line {0:00}", i); _with1.Rows.Add(r); } cvs.Source = dt; } return cvs.View; } } //private Action<object> cmd2 = new Action<object>(Cmd2Exec); private Action<object> test() { Action<object> cmd2 = new Action<object>(Cmd2Exec); return cmd2; } public ICommand cmd { get { return new RelayCommand(test()); } } public void Cmd2Exec(object obj) { Prop2 = string.Format("Button is pressed: {0:HH:mm:ss.fff}", DateTime.Now); } private string _prop2 = "Button is not pressed"; public string Prop2 { get { return this._prop2; } set { if (this._prop2 == value) return; this._prop2 = value; Notify("Prop2"); } } public event PropertyChangedEventHandler PropertyChanged; protected void Notify(string propName) { if (this.PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } public class RelayCommand : ICommand { private readonly Action<object> _execute; private readonly Predicate<object> _canExecute; public RelayCommand(Action<object> execute) : this(execute, null) { } public RelayCommand(Action<object> execute, Predicate<object> canExecute) { if (execute == null) { throw new ArgumentNullException("execute"); } this._execute = execute; this._canExecute = canExecute; } [DebuggerStepThrough] public bool CanExecute(object parameter) { return this._canExecute == null ? true : this._canExecute(parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { this._execute(parameter); } }
参考:
Button-Command in a DataGridTemplateColumn.Header
http://social.msdn.microsoft.com/Forums/de-DE/wpfde/thread/ddb1c7dc-fa07-459c-ac5c-6afc5b94f677/
Yoyo Jiang[MSFT]
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help. -
jiang你好,谢谢你的回答!你说的办法可以成功的绑定了,但是我遇到了新的问题,
DataGrid dg; using (FileStream fs = new FileStream("MyDataGrid.xaml", FileMode.Open, FileAccess.Read)) { dg = (DataGrid)XamlReader.Load(fs); } grid.Children.Add(dg);
我用XamlReader的方式来加载我的DataGrid的话,
Command="{Binding Source={StaticResource vm}, Path=cmd}"
就会报错了, 请问要如何修改呢? -
报的错误是什么呢?
这个MyDataGrid.Xaml文件,可以提供么?
谢谢。
Yoyo Jiang[MSFT]
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help. -
MyDataGrid.Xaml
<DataGrid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ItemsSource="{Binding Path = MyModels}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0,0,0,68" Name="dg" VerticalAlignment="Stretch"> <DataGrid.Columns> <DataGridTemplateColumn > <DataGridTemplateColumn.HeaderTemplate> <DataTemplate> <CheckBox x:Name="ckbSelectedAll" Command="{Binding Source={StaticResource vm}, Path=ShowtCmd}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.HeaderTemplate> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox x:Name="ckbSelectedAll" IsChecked="{Binding IsCheck}" Command="{Binding ShowtCmd}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="id"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Id}"></TextBlock> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="button"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Name="bt" Content="{Binding Name}" Style="{StaticResource LinkButton}" Command="{Binding ShowtCmd}"></Button> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
主窗体
<Window x:Class="_5._30DataGrid.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" xmlns:ViewModels="clr-namespace:_5._30DataGrid"> <Window.Resources> <ViewModels:MyViewModel x:Key="vm" /> </Window.Resources> <Grid Name="grid" DataContext="{Binding Source={StaticResource vm}}"> </Grid> </Window>
主窗体的Loaded事件
void MainWindow_Loaded(object sender, RoutedEventArgs e) { DataGrid dg; using (FileStream fs = new FileStream("MyDataGrid.xaml", FileMode.Open, FileAccess.Read)) { dg = (DataGrid)XamlReader.Load(fs); } grid.Children.Add(dg); }
报错
-
那么不用StaticResource, 直接绑定到DataGrid上面试试吧。
<Button Content="Head" Command="{Binding ElementName=dg, Path=DataContext.cmd}"/> ——————————————————————————分割线—————————————————————————— <Window.Resources> <loc:ViewModel x:Key="vm"/> </Window.Resources> <StackPanel DataContext="{Binding Source={StaticResource vm}}"> <DataGrid Name="dg" ItemsSource="{Binding View}" AutoGenerateColumns="False" Tag="123"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding col1}" > <DataGridTextColumn.HeaderTemplate> <DataTemplate> <Button Content="Head" Command="{Binding ElementName=dg, Path=DataContext.cmd}"/> </DataTemplate> </DataGridTextColumn.HeaderTemplate> </DataGridTextColumn> </DataGrid.Columns> </DataGrid> <Label Content="{Binding Prop2}"/> </StackPanel>
谢谢。
Yoyo Jiang[MSFT]
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- 已标记为答案 huanghy 2013年6月5日 2:14