小さなPOCでこの問題に遭遇しましたが、より大きなプロジェクトで動作するようになり、その理由を見つけることができました。それが役立つかどうかはわかりませんが、ここで彼のコンテキストと解決策を示します。
この問題は、itemSource がビューモデルで公開されているコレクションにバインドされている Xceed データグリッドのボタンにコマンドをバインドしようとしたときに発生しました。
景色 :
<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; }
}
}
THE ADAPTER (データグリッドの行で表されます)。Relay コマンドは、基本的な 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);
}
}
}
}
そして、これは私のアプリがアダプターを作成してコレクションに追加しようとするとすぐに生成される例外です
Message="'CommandConverter' は 'UnIfied.Module.UI.Client.Adapters.RelayCommand' を 'System.String' に変換できません。" Source="System" StackTrace: System.ComponentModel.TypeConverter.GetConvertToException (オブジェクト値、型 destinationType) で System.Windows.Input.CommandConverter.ConvertTo (ITypeDescriptorContext コンテキスト、CultureInfo カルチャ、オブジェクト値、型 destinationType) で System.ComponentModel. TypeConverter.ConvertTo(Object value, Type destinationType) at System.Windows.Controls.ContentPresenter.DefaultTemplate.DoDefaultExpansion(TextBlock textBlock, オブジェクト コンテンツ, ContentPresenter コンテナー) (その他)
この問題は、データグリッドが AutoCreateColumns に構成されている (つまり、アダプターのプロパティに基づいている) ために発生しました。このプロパティを false に切り替えるだけで、すべてが再びまっすぐになりました。
これが皆さんの助けになることを願っています!
――ブルーノ