Я только что столкнулся с этой проблемой, хотя в небольшом POC, хотя я заставил его работать в более крупном проекте, и мне удалось выяснить, почему.Не знаю, может ли это помочь, но здесь его контекст и решение.
Проблема возникла при попытке привязать команду к кнопке в сетке данных Xceed, которой itemSource был привязан для коллекции, представленной вmy viewModel.
ВИД:
<UserControl x:Class="UnIfied.Module.UI.Client.Screens.Alerts.AlertsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:DataGrid="clr-namespace:Xceed.Wpf.DataGrid;assembly=Xceed.Wpf.DataGrid" xmlns:xcdg="clr-namespace:Xceed.Wpf.DataGrid.Views;assembly=Xceed.Wpf.DataGrid" xmlns:ThemePack="clr-namespace:Xceed.Wpf.DataGrid.ThemePack;assembly=Xceed.Wpf.DataGrid.ThemePack.1">
<Grid>
<DataGrid:DataGridControl Grid.Column="0"
Name="alertsBlotter"
ItemsSource="{Binding AlertsSource}"
SelectionMode="Single"
NavigationBehavior="RowOnly"
ItemScrollingBehavior="Immediate" ReadOnly="True"
AutoCreateColumns="false">
<DataGrid:DataGridControl.Columns>
<DataGrid:UnboundColumn FieldName="Acquit" Title="Acquit Alert" ReadOnly="True" ShowInColumnChooser="False">
<DataGrid:UnboundColumn.CellContentTemplate>
<DataTemplate>
<Button
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type DataGrid:DataRow}}}"
Content="X" Command="{Binding AcquitAlertCommand}"/>
</DataTemplate>
</DataGrid:UnboundColumn.CellContentTemplate>
</DataGrid:UnboundColumn>
<DataGrid:Column FieldName="AlertId" ReadOnly="True" Title="Alert Id" IsMainColumn="True" />
<DataGrid:Column FieldName="Time" ReadOnly="True" Title="Creation Time" />
<DataGrid:Column FieldName="AlertStatus" ReadOnly="True" Title="Status" />
<DataGrid:Column FieldName="RelatedTrade" ReadOnly="True" Title="CT Id" />
<DataGrid:Column FieldName="Status" ReadOnly="True" Title="CT Status" />
</DataGrid:DataGridControl.Columns>
<DataGrid:DataGridControl.Resources>
<Style x:Key="{x:Type DataGrid:ScrollTip}" TargetType="DataGrid:ScrollTip">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGrid:DataGridControl.Resources>
<DataGrid:DataGridControl.View>
<xcdg:TableView>
<xcdg:TableView.Theme>
<ThemePack:WMP11Theme />
</xcdg:TableView.Theme>
</xcdg:TableView>
</DataGrid:DataGridControl.View>
</DataGrid:DataGridControl>
</Grid>
МОДЕЛЬ ВИДА
class AlertsViewModel : Presenter<IAlerts>
{
private readonly IAlertsService alertsService;
public AlertsViewModel(IAlerts view, IAlertsService aService)
: base(view)
{
alertsService = aService;
view.SetDataContext(this);
}
public ObservableCollection<AlertAdapter> AlertsSource
{
get { return alertsService.AlertsSource; }
}
}
АДАПТЕР (который затем будет представлен строкой всетка данных).Команда ретрансляции является базовой реализацией ICommand.
public class AlertAdapter : BindableObject
{
private readonly RelayCommand acquitAlert;
public AlertAdapter()
{
AlertStatus = AlertStatus.Raised;
acquitAlert = new RelayCommand(ExecuteAqcuiteAlert);
}
public RelayCommand AcquitAlertCommand
{
get { return acquitAlert; }
}
private void ExecuteAqcuiteAlert(object obj)
{
AlertStatus = AlertStatus.Cleared;
}
private static readonly PropertyChangedEventArgs AlertStatusPropertyChanged = new PropertyChangedEventArgs("AlertStatus");
private AlertStatus alertStatus;
/// <summary>
/// Gets or sets the AlertStatus
/// </summary>
public AlertStatus AlertStatus
{
get { return alertStatus; }
set
{
if (AlertStatus != value)
{
alertStatus = value;
RaisePropertyChanged(AlertStatusPropertyChanged);
}
}
}
private static readonly PropertyChangedEventArgs AlertIdPropertyChanged = new PropertyChangedEventArgs("AlertId");
private Guid alertId;
/// <summary>
/// Gets or sets the AlertId
/// </summary>
public Guid AlertId
{
get { return alertId; }
set
{
if (AlertId != value)
{
alertId = value;
RaisePropertyChanged(AlertIdPropertyChanged);
}
}
}
private static readonly PropertyChangedEventArgs StatusPropertyChanged = new PropertyChangedEventArgs("Status");
private ComponentTradeStatus status;
/// <summary>
/// Gets or sets the CtStatus
/// </summary>
public ComponentTradeStatus Status
{
get { return status; }
set
{
if (Status != value)
{
status = value;
RaisePropertyChanged(StatusPropertyChanged);
}
}
}
private static readonly PropertyChangedEventArgs RelatedTradePropertyChanged = new PropertyChangedEventArgs("RelatedTrade");
private Guid relatedTrade;
/// <summary>
/// Gets or sets the RelatedTrade
/// </summary>
public Guid RelatedTrade
{
get { return relatedTrade; }
set
{
if (RelatedTrade != value)
{
relatedTrade = value;
RaisePropertyChanged(RelatedTradePropertyChanged);
}
}
}
private static readonly PropertyChangedEventArgs TimePropertyChanged = new PropertyChangedEventArgs("Time");
private DateTime time;
/// <summary>
/// Gets or sets the Time
/// </summary>
public DateTime Time
{
get { return time; }
set
{
if (Time != value)
{
time = value;
RaisePropertyChanged(TimePropertyChanged);
}
}
}
}
И вот исключение, сгенерированное, как только мое приложение попыталось создать адаптер и добавить его в коллекцию.
System.NotSupportedException не обрабатывалосьСообщение = "'CommandConverter' не может преобразовать 'UnIfied.Module.UI.Client.Adapters.RelayCommand' в 'System.String'."Source = "System" StackTrace: at System.ComponentModel.TypeConverter.GetConvertToException (значение объекта, тип destinationType) в System.Windows.Input.CommandConverter.ConvertTo (контекст ITypeDescriptorContext, культура CultureInfo, значение объекта, тип destinationTypeM).TypeConverter.ConvertTo (значение объекта, тип destinationType) в System.Windows.Controls.ContentPresenter.DefaultTemplate.DoDefaultExpansion (TextBlock textBlock, содержимое объекта, контейнер ContentPresenter) (ETC.)
Проблемабыло вызвано тем, что моя сетка данных была настроена на AutoCreateColumns (то есть на основе свойств адаптера).Просто переключили это свойство на false, а затем все снова пошло прямо.
Надеюсь, это поможет вам, ребята!
- Бруно