Resharper/Intellisense 推理在DataGridTemplate
.
这可能会导致混淆,为了纠正这种情况,DataTemplate 应该有一个明确的 DataType 引用该行绑定到的类型。
我发现有两种方法可以解决您的问题,使用相对绑定的命令,以便它使用 DataGrid 的上下文进行绑定,而不是当前行,或者在具有您的上下文的元素上创建 x:Name 属性希望绑定到。
我相信,如果您尝试访问祖先,则相对绑定会更清晰,但是如果您需要绑定到树中其他地方的某些东西,那么 ElementName 可能会允许这样做。
XAML:
<Window x:Class="TestBindings.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestBindings"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:WindowViewModel/>
</Window.DataContext>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<GroupBox x:Name="Test" Header="Grid" Grid.Column="0"> <!-- #2 Add a name to the element you need to bind to. -->
<DataGrid ItemsSource="{Binding RowList}" IsSynchronizedWithCurrentItem="True" SelectionUnit="FullRow" >
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="local:RowViewModel"><!-- Needed for correct inference in XAML editor -->
<!-- #1 Cleaner solution as it doesn't depend on names -->
<Button Content="{Binding Path=RowCount}" Command="{Binding Path=DataContext.NineCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding}" />
<!-- #2 Naming the element explicitly probably allows you to jump elsewhere in the tree -->
<Button Content="{Binding Path=RowCount}" Command="{Binding Path=DataContext.NineCommand, ElementName=Test}" CommandParameter="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</GroupBox>
<GroupBox Header="{Binding Path=SelectedRow.RowCount}" Grid.Column="1">
<Label Content="{Binding Path=RowList/RowCount}"></Label>
</GroupBox>
</Grid>
</Window>
班级:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using Microsoft.Expression.Interactivity.Core;
using Microsoft.Practices.Prism.ViewModel;
namespace TestBindings
{
public class RowViewModel : NotificationObject
{
private static int _max = 0;
private int _rowCount;
public int RowCount
{
get { return _rowCount; }
set
{
if (_rowCount == value) return;
_rowCount = value;
RaisePropertyChanged(nameof(RowCount));
}
}
public RowViewModel()
{
_rowCount = _max++;
}
}
public class TypedCommand<T> : ICommand
{
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
public TypedCommand(Action<T> execute, Predicate<T> canExecute = null)
{
this._canExecute = canExecute;
this._execute = execute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute((T) parameter);
}
public void Execute(object parameter)
{
_execute?.Invoke((T) parameter);
}
public event EventHandler CanExecuteChanged;
}
public class WindowViewModel : NotificationObject
{
public ObservableCollection<RowViewModel> RowList { get; } = new ObservableCollection<RowViewModel>();
private RowViewModel _selectedRow;
public RowViewModel SelectedRow
{
get { return _selectedRow; }
private set
{
if (_selectedRow == value) return;
_selectedRow = value;
RaisePropertyChanged(nameof(SelectedRow));
}
}
private static readonly Action<RowViewModel> DeleteAction = new Action<RowViewModel>(row => row.RowCount=99);
public ICommand NineCommand { get; } = new TypedCommand<RowViewModel>(DeleteAction);
public WindowViewModel()
{
//0
RowList.Add(new RowViewModel());
//1
RowList.Add(new RowViewModel());
//2
RowList.Add(new RowViewModel());
}
}
}