My Problem:
DataGrid
column with a button, which is bound to a Command (that part works)DataRow
.DataTrigger
depending on the DataContext
I use, but not both at the same time.I am stuck with the following code:
<xcdg:Column FieldName="OpenInPiWebIdentifier"
Title="PiWeb Report"
VisiblePosition="6">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<Button DataContext="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:DataGridControl.ParentDataGridControl).DataContext}"
Content="Open PiWeb"
Command="{Binding OpenPiWebCommand}"
CommandParameter="{Binding DataContext.ResultData/PiWebReport, Mode=OneWay, RelativeSource={RelativeSource Self}}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding PiWebReport}"
Value="{x:Null}">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>
And the view model implementation of the command:
public ICommand OpenPiWebCommand
{
get
{
return _OpenPiWebCommand;
}
set
{
if (value != _OpenPiWebCommand)
{
_OpenPiWebCommand = value;
OnPropertyChanged("OpenPiWebCommand");
}
}
}
private ICommand _OpenPiWebCommand;
In the constructor I initialize the command:
OpenPiWebCommand = new RelayCommand(new Action<object>(OpenPiWeb));
The property PiWebReport
belongs to a class ResultDataV1
. All data is put into this property ResultData = new ObservableCollection<ResultDataV1>();
which is displayed in the DataGrid
as columns/rows.
So, now I can access either the property value PiWebReport
or the command, depending on the context I use, but not both at the same time.
The data class:
public class ResultDataV1
{
public ResultDataV1(long dataId, DateTime dateTime, DateTime? endDateTime, string partId, string scanId, bool measurementNotVolumejoin, string piWebReport, FileInfo volumeFileInfo, FileInfo volumeVglFileInfo, DirectoryInfo volumeDirectoryInfo, string inspectionPlanName, string paletteName, AutomationStateEnum? automationState);
public AutomationStateEnum? AutomationState { get; }
public long DataId { get; }
public DateTime DateTime { get; }
public DateTime? EndDateTime { get; }
public string InspectionPlanName { get; }
public bool MeasurementNotVolumejoin { get; }
public string PaletteName { get; }
public string PartId { get; }
public string PiWebReport { get; }
public string ScanId { get; }
public List<SubResultDataV1> SubResults { get; }
public DirectoryInfo VolumeDirectoryInfo { get; }
public FileInfo VolumeFileInfo { get; }
public FileInfo VolumeVglFileInfo { get; }
}
The main idea is to use the ICommand.CanExecute Method. Initially the button becomes enabled or disabled based on the value of the method (of the bound ICommand
instance). Also, firing ICommand.CanExecuteChanged Event can be used to notify the user-interface (Button
class) about the property change.
The implementation of the structure:
internal sealed class ResultData
{
private readonly string piWebReport;
public ResultData(string piWebReport)
{
this.piWebReport = piWebReport;
}
public string PiWebReport
{
get { return this.piWebReport; }
}
}
The implementation of the ViewModel
class:
internal sealed class MainViewModel
{
private readonly IEnumerable<ResultData> items = new[]
{
new ResultData("Report 00"),
new ResultData("Report 01"),
new ResultData("Report 02"),
new ResultData(null)
};
private readonly ICommand openPiWebCommand;
public MainViewModel()
{
openPiWebCommand = new RelayCommand<ResultData>(
OpenPiWeb,
x => x != null && x.PiWebReport != null);
}
public IEnumerable<ResultData> Items
{
get { return items; }
}
public ICommand OpenPiWebCommand
{
get { return openPiWebCommand; }
}
private void OpenPiWeb(ResultData data)
{
// Implement the command logic.
}
}
XAML:
<Window x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid"
...>
<Grid>
<xcdg:DataGridControl ItemsSource="{Binding Items}">
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="PiWebReport"
Title="PiWeb Report">
<xcdg:Column.DisplayMemberBindingInfo>
<xcdg:DataGridBindingInfo Path="." ReadOnly="True" />
</xcdg:Column.DisplayMemberBindingInfo>
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<Grid>
<Button Content="Open PiWeb"
CommandParameter="{Binding}"
Command="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:DataGridControl.ParentDataGridControl).DataContext.OpenPiWebCommand}" />
</Grid>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
</Window>
References:
Column.DisplayMemberBindingInfo
usage: Difficult choice of grid for projects on WPF.Hope this is useful for you!