2015-04-29 3 views
-1

Проблема, с которой я столкнулся, - заставить мою кнопку работать со связыванием. Я не уверен, что установить DataContext. Я получаю эту ошибку с моим обязательным:Почему моя команда привязки для моей кнопки не работает?

System.Windows.Data Error: 40 : BindingExpression path error: 'ClickMeCommand' property not found on 'object' ''Person' (HashCode=13029119)'. BindingExpression:Path=ClickMeCommand; DataItem='Person' (HashCode=13029119); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')

Что я делаю здесь у меня есть ListView в XAML и у меня есть Grid View с тремя столбцами. В одном столбце хранится Имя из объекта Person, второй столбец сохраняет Date из объекта Person, а третий столбец для всех в списке - один и тот же. Когда нажимается кнопка, я хочу выполнить команду для удаления задачи из моей наблюдаемой коллекции и обновления списка. Я знаю, как это сделать, но я не могу заставить команду привязки для кнопки работать.

<ListView x:Name="List" HorizontalAlignment="Left" Margin="0,0,0,-2"` Width="292" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Height="Auto"> 
        <ListView.ItemContainerStyle> 
         <Style TargetType="{x:Type ListViewItem}"> 
          <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
        </Style> 
       </ListView.ItemContainerStyle> 
       <ListView.View> 
        <GridView> 
         <GridView.ColumnHeaderContainerStyle> 
          <Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="{x:Type GridViewColumnHeader}"> 
           <Setter Property="IsHitTestVisible" Value="False"/> 
          </Style> 
         </GridView.ColumnHeaderContainerStyle> 
         <GridViewColumn x:Name="Column1" Header="Assignment" DisplayMemberBinding="{Binding Name}" Width="190"/> 
         <GridViewColumn x:Name="Column2" Header="Date" DisplayMemberBinding="{Binding Date}" Width="45"/> 
         <GridViewColumn Header="Edit" Width="35" CellTemplate="{StaticResource editColumnTemplate}"> 
         </GridViewColumn> 
        </GridView> 
       </ListView.View> 
      </ListView> 


<Window.Resources> 
     <DataTemplate x:Key="editColumnTemplate"> 
      <StackPanel Orientation="Horizontal"> 
       <Button x:Name="deleteButton" Content="X" Command="{Binding Path=ClickMeCommand}" HorizontalAlignment="Stretch"/> 
      </StackPanel> 
     </DataTemplate> 
</Window.Resources> 

//

private class Person 
     { 
      public String Name { get; set; } 
      public String Date { get; set; } 

     } 

В моем коде позади, я создаю новую вкладку и добавьте ListView в нем. Каждый раз, когда я добавляю нового человека, он добавляет строку в список со своим именем/датой и кнопкой в ​​третьем столбце.

public MainWindow(){ 
    InitializeComponent(); 
    this.DataContext = new MainViewModel(); 
} 
TabItem newItem = new TabItem(); 
ListView newList = new ListView(); 
ObservableCollection<TabItem> newSource = new ObservableCollection<TabItem>(); 
newList.ItemsSource = newSource; 
TabControl.Items.Add(newItem); 

Эта кнопка привязана к команде ClickMeCommand, как вы можете видеть сверху. Это класс:

public class MainViewModel 
{ 
    public MainViewModel() 
    { 

    } 

    private ICommand clickMeCommand; 
    public ICommand ClickMeCommand 
    { 
     get 
     { 
      if (clickMeCommand == null) 
       clickMeCommand = new RelayCommand(i => this.ClickMe(), null); 
      return clickMeCommand; 
     } 
    } 

    private void ClickMe() 
    { 
     MessageBox.Show("You Clicked Me"); 
    } 
}  
public class RelayCommand : ICommand 
{ 
    readonly Action<object> execute; 
    readonly Predicate<object> canExecute; 

    public RelayCommand(Action<object> executeDelegate, Predicate<object> canExecuteDelegate) 
    { 
     execute = executeDelegate; 
     canExecute = canExecuteDelegate; 
    } 

    bool ICommand.CanExecute(object parameter) 
    { 
     return canExecute == null ? true : canExecute(parameter); 
    } 

    event EventHandler ICommand.CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    void ICommand.Execute(object parameter) 
    { 
     execute(parameter); 
    } 
} 

ответ

1

Вы определили кнопку внутри DataTemplate в ListView пункта, и он не может получить доступ к команде, которая в DataContext в окне, так что вам нужно использовать RelativeSource привязки см ниже шаблон код.

<DataTemplate x:Key="editColumnTemplate"> 
     <StackPanel Orientation="Horizontal"> 
      <Button x:Name="deleteButton" Content="X" Command="{Binding Path=DataContext.ClickMeCommand, 
         RelativeSource={RelativeSource Mode=FindAncestor, 
                AncestorType=Window}}" HorizontalAlignment="Stretch"/> 
     </StackPanel> 
    </DataTemplate> 
-1

ListView автоматически устанавливает DataContext для каждого представления элемента как самого элемента. Вот почему {Binding Name} работает и {Binding ClickMeCommand} не делает, таким образом, ошибку 'ClickMeCommand' property not found on 'object' ''Person'.

Обычный способ сохранить ссылку на корневой DataContext в WPF является, чтобы сохранить его в представлении ResourceDictionary:

<ListView.Resources> 
    <local:BindingProxy x:Key="rootDataContext" Data="{Binding}" /> 
</ListView.Resources> 

Затем в шаблоне элемента:

<GridViewColumn Command="{Binding Data.ClickMeCommand, Source={StaticResource proxy}}" /> 

связывании прокси класса :

public class BindingProxy : Freezable 
{ 
    #region Overrides of Freezable 

    protected override Freezable CreateInstanceCore() 
    { 
     return new BindingProxy(); 
    } 

    #endregion 

    public object Data 
    { 
     get { return (object)GetValue(DataProperty); } 
     set { SetValue(DataProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty DataProperty = 
     DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); 
} 

More on the topic/Source

Смежные вопросы