none
使用mvvm在DataGrid的DataGridTemplateColumn.HeaderTemplate在使用Command绑定不成功 RRS feed

  • 问题

  • <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里面要如何绑定
    2013年5月30日 10:15

答案

  • 那么不用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
    2013年6月4日 6:53
    版主

全部回复

  • 你好!

    可能是由于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.

    2013年6月3日 9:20
    版主
  • 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}"
    就会报错了, 请问要如何修改呢?
    2013年6月4日 1:42
  • 报的错误是什么呢?

    这个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.

    2013年6月4日 3:23
    版主
  • 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);
            }

    报错

    2013年6月4日 3:40
  • 那么不用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
    2013年6月4日 6:53
    版主
  • 可以了,谢谢!
    2013年6月5日 2:14