input control in datagrid - c#

how can you control what the user inputs in datagrid.
i need to be able to control input of each DataGridTextColumn.
if possible i want to be able to control the input when a character is typed in the datagrid. so selectionchanged for listbox.
sadly what i have now isn't working.
<DataGrid AutoGenerateColumns="False" Grid.Row="1" ItemsSource="{Binding ContactList}" SelectedItem="{Binding SelectedContact,UpdateSourceTrigger=PropertyChanged}" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="25" Binding="{Binding ID}" IsReadOnly="True"/>
<DataGridTextColumn Header="Naam" Width="1*" Binding="{Binding Name}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<cmd:EventToCommand Command="{Binding TestCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGridTextColumn>
<DataGridTextColumn Header="Bedrijf" Width="1*" Binding="{Binding Company}"/>
<DataGridTemplateColumn Width="1*" Header="Functie">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding JobRoleList}" DisplayMemberPath="Name" SelectedItem="{Binding JobRole.Name,UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" SelectedValue="{Binding JobRole.ID,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
thanks
edit i get an XamlParceException
xaml
<DataGridTemplateColumn Header="Naam" CellTemplate="{StaticResource ContactNameTemplate}" CellEditingTemplate="{StaticResource EditingContactNameTemplate}" />
dictionary
<DataTemplate x:Key="ContactNameTemplate" >
<TextBox HorizontalAlignment="Center">
<TextBox.Text>
<Binding Path="Name" Source="{Binding Name}" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<c:Text Min="21" Max="130"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</DataTemplate>
<DataTemplate x:Key="EditingContactNameTemplate">
<TextBox HorizontalAlignment="Center">
<TextBox.Text>
<Binding Path="Name" Source="{Binding Name}" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<c:Text Min="21" Max="130"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</DataTemplate>

Related

How to simplify verbose WPF DataGrid Xaml?

I have a WPF DataGrid with many columns (below I showed only 3 columns for simplicity). To mark up a single column it takes almost 20 lines of code and it repeats for every column. The only difference between the columns is the header text and the binding.
MainView.xaml:
<Window x:Class="UserInterface.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Converters="clr-namespace:UserInterface.Converters"
xmlns:UiUtilities="clr-namespace:.UserInterface.UIUtilities"
mc:Ignorable="d"
Icon="Application.ico"
Title="{Binding WindowTitle}"
SizeToContent="WidthAndHeight"
ResizeMode="NoResize"
DataContext="{Binding MainViewModel}">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
<Converters:VisibleIfOfTypeXConverter x:Key="VisibleIfOfTypeX" />
</Window.Resources>
<DataGrid ItemsSource="{Binding DataModel}" HeadersVisibility="Column" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Header1">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="UserInterface:SomeType">
<Grid>
<TextBox Visibility="{Binding Converter={StaticResource VisibleIfOfTypeX}}">
<TextBox.Text>
<Binding Path="P1Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<UiUtilities:NumberRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Header2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="UserInterface:SomeType">
<Grid>
<TextBox Visibility="{Binding Converter={StaticResource VisibleIfOfTypeX}}">
<TextBox.Text>
<Binding Path="P2Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<UiUtilities:NumberRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Header3">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="UserInterface:SomeType">
<Grid> <TextBox Visibility="{Binding Converter={StaticResource VisibleIfOfTypeX}}">
<TextBox.Text>
<Binding Path="P3Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<UiUtilities:NumberRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Window>
I'm still a beginner in WPF, but I assume there must be a less verbose way to implement this. I imagine there must be some sort of "templating" or components as they are used in other UI Frameworks.
Could we create some sort of component (I call it "MyCustomDataGridColumn"), that we could use like this:
<DataGrid ItemsSource="{Binding DataModel}">
<DataGrid.Columns>
<MyCustomDataGridColumn Header="Header1" TextBoxBinding="P1Text">
<MyCustomDataGridColumn Header="Header2" TextBoxBinding="P2Text">
<MyCustomDataGridColumn Header="Header3" TextBoxBinding="P3Text">
</DataGrid.Columns>
</DataGrid>
How could we achieve this? Or are there other/better ways to reduce verbosity?

SelectionChanged event of datagrid is not firing in mvvm way

//I am having a Nested datagrid
and i need to fire the event when inner grid row selection changes.
<DataGrid ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
HeadersVisibility="Row"
Height="{Binding ElementName=itemsgrid,Path=ActualHeight}"
Grid.Row="1"
RowDetailsVisibilityMode="Visible"
CanUserAddRows="false"
VerticalAlignment="Top"
AutoGenerateColumns="False"
SelectedItem="{Binding SelectedBasketItem}"
ItemsSource="{Binding SelectedOrderBasketItems}"
CanUserDeleteRows="True">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
CanUserAddRows="false"
HeadersVisibility="Row"
AutoGenerateColumns="False"
ItemsSource="{Binding SelectedBasketItems}"
SelectedValue="{Binding SelectedBasketItemValue}"
SelectedIndex="{Binding SelectedOrderItemIndex}"
SelectedItem="{Binding SelectedSpecificItemInBasket, Mode=TwoWay}"
DataGrid.SelectionMode="Single"
Style="{StaticResource GridItemsControlStyle}"
ctrls:DragDrop.DropHandler="{Binding DropHandler}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DataContext.DgSelectionChangedCommand,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn IsReadOnly="True"
Binding="{Binding Path=ItemName}"
Width="195">
</DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=RulesCount}"
Background="{Binding Path=RulesCount ,Converter={StaticResource ItemColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="115">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=LinkedOrderCount}"
Background="{Binding Path=LinkedOrderCount ,Converter={StaticResource ItemColourConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="55">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=SDICount}">
<Label.Background>
<MultiBinding Converter="{StaticResource SdiItemColourConverter}">
<Binding ElementName="SDIMaxCnt"
Path="Value" />
<Binding Path="SDICount" />
</MultiBinding>
</Label.Background>
</Label>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
//My Delegate Command initialization in ViewModel
protected override void InitializeCommands()
{
DgSelectionChangedCommand= new DelegateCommand<object>(DGSelectionChanged);
}
//My Method in the view model to be called when selection changed event is fired
void DGSelectionChanged(object obj)
{
//Logic
}
The event gets fired when i use the same event in code behind . i am trying to use interaction trigger to achieve the same in mvvm way .Not sure what i am missing .Any help is greatly appreciated.
Set the AncestorLevel of the RelativeSource to 2:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DataContext.DgSelectionChangedCommand,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}, AncestorLevel=2}}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Autopostback is the mechanism, by which the page will be posted back to the server automatically based on some events in the web controls. In some of the web controls, the property called auto post back.
which if set to true, will send the request to the server when an event happens in the control.
AutoPostBack=True;
please go through the link for more:
Difference between AutoPostBack=True and AutoPostBack=False?

WPF Datagrid Column Visibility not working with MultiBinding

I am trying to control the visibility of a DataGridTextColumn using two Boolean values. One of the values is being set by a combo box and I am able to see in the debugger that Boolean values are being properly handled by the booleanAllTrueConverter.
My problem is that the converter value being returned has no effect on the column visibility. The column is always visible even when FALSE is returned from the converter.
I would certainly appreciate any ideas that are offered.
Thanks.
<DataGrid
Name="myDataGrid"
ItemsSource="{Binding Source={StaticResource ZZZZ}}"
AutoGenerateColumns="False"
IsReadOnly="True"
KeyboardNavigation.TabNavigation="None"
>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding SomeItems}" >
<DataGridTextColumn.Visibility>
<MultiBinding Converter="{StaticResource booleanAllTrueConverter}">
<Binding
Source="{StaticResource ProxyElement}"
Path="DataContext.IsBlahVisible"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
/>
<Binding
Source="{StaticResource ProxyElement}"
Path="DataContext.AreColumnsVisible"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
/>
</MultiBinding>
</DataGridTextColumn.Visibility>
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<local:ComboBox
Grid.Column="0"
Width="22"
Height="36"
HorizontalAlignment="Right"
VerticalAlignment="Center"
ItemsSource="{Binding DataContext.SomeItems, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
SelectedItems="{Binding DataContext.SelectedSomeItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
></local:ComboBox>
<TextBlock
Text="SomeItems"
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.ColumnSpan="2"
Height="16"
Margin="0,3"
Width="37"
/>
</Grid>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
You need to return either Visibility.Visible instead of true or return Visibility.Collapsed instead of false from booleanAllTrueConverter

Binding gives UnsetValue on multiple binding

I have a datagrid which gets its data out of a datatable like
Inside if there is a textbox with a contextmenu and this contextmenu has a converter (with multibinding)
The problem is i datatable the binded data has 1 or 0 as data but in the converter i get UnsetValue.
This is the xaml code:
<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" Margin="0,1,0,0" x:Name="TrackingDataGrid" IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False" IsManipulationEnabled="True" CanUserResizeColumns="False" ItemsSource="{Binding TrackingTable}" ColumnHeaderStyle="{DynamicResource dataGridColumnStyle}" Style="{DynamicResource dataGridStyle}" EnableColumnVirtualization="True" IsEnabled="True" BorderThickness="0" CellStyle="{DynamicResource CellStyleBase}" VerticalGridLinesBrush="#FFA0A7AD" RowHeight="30" MinRowHeight="20" GridLinesVisibility="None" SelectionMode="Single" Grid.Row="1" Grid.ColumnSpan="10" Panel.ZIndex="4" MinHeight="30" Loaded="TrackingDataGrid_Loaded" CanUserReorderColumns="False" VerticalScrollBarVisibility="Disabled" ScrollViewer.CanContentScroll="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Process Time" IsReadOnly="True" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DeliveryDate}" TextTrimming="CharacterEllipsis" >
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem x:Name="StandbyProcessMenuITem" Header="StandBy Process" Click="StandbyProcessMenuITem_Click" >
<!--<MenuItem.Visibility>
<MultiBinding Converter="{StaticResource RowUndoButtonVisibility}">
<Binding Path="ProductIsStandby" />
<Binding Path="ProductIsDone" />
</MultiBinding>
</MenuItem.Visibility>-->
</MenuItem>
<MenuItem x:Name="UndoProcessMenuITem" Header="Undo Process" Click="UndoProcessMenuITem_Click" >
<MenuItem.Visibility>
<MultiBinding Converter="{StaticResource RowUndoButtonVisibility}">
<Binding Path="{Binding ProductIsStandby}" />
<Binding Path="{Binding ProductIsDone}" />
</MultiBinding>
</MenuItem.Visibility>
</MenuItem>
<MenuItem x:Name="FinishProcessMenuITem" Header="Finish Process" Click="FinishProcessMenuITem_Click">
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
The DataContext of a MenuItem is not the same as the DataContext of the CellTemplate but you could use a RelativeSource to bind to the PlacementTarget of the ContextMenu:
<MenuItem x:Name="UndoProcessMenuITem" Header="Undo Process" Click="UndoProcessMenuITem_Click" >
<MenuItem.Visibility>
<MultiBinding Converter="{StaticResource RowUndoButtonVisibility}">
<Binding Path="{Binding PlacementTarget.DataContext.ProductIsStandby, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
<Binding Path="{Binding PlacementTarget.DataContext.ProductIsDone, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
</MultiBinding>
</MenuItem.Visibility>
</MenuItem>

Bind Tag of the TextBlock

I have a DataGrid as shown in the image below:
In DataGrid at the third level Date column is a DataGridTemplateColumn.
Here is the code of the above mentioned Date Column:
<DataGridTemplateColumn Header="Date" Width="5*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringFormat='{}{0:dd/MM/yyyy}'}"
Tag= ?????? />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
As mentioned in the above code I want to bind Tag Property of TextBlock to the number of occurences of same date in this column.
Example of what I want:
Suppose I have 5 rows
Date | Tag
-------------+----------
20/08/2012 | 1
20/08/2012 | 2
21/08/2012 | 1
23/08/2012 | 1
20/08/2012 | 3
Suppose you don't have code then please give me the logic I will try to code it myself.
Update: Full code of datagrid shown in the above image
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding DataContext.Patients, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
SelectedItem="{Binding SelectedPatient}" RowDetailsVisibilityMode="VisibleWhenSelected"
IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow" >
<DataGrid.Resources>
<Style x:Key="VerticalCenter" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
</Style>
<Style x:Key="VerticalAndHorizontalCenter" TargetType="FrameworkElement" >
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
<Style x:Key="VerticalAndHorizontalCenterTextBlock" TargetType="TextBlock"
BasedOn="{StaticResource VerticalAndHorizontalCenter}"/>
<Style x:Key="VerticalAndHorizontalCenterHeader" TargetType="{x:Type DataGridColumnHeader}"
BasedOn="{StaticResource VerticalAndHorizontalCenter}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding PatientName}" Header="Patient Name" Width="25*"
ElementStyle="{StaticResource VerticalCenter}"/>
<DataGridTextColumn Binding="{Binding City}" Header="City" Width="15*"
ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}"
HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
<DataGridTextColumn Binding="{Binding TypeSex.Value}" Header="Sex" Width="10*"
ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}"
HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
<DataGridTextColumn Binding="{Binding Age}" Header="Age" Width="5*"
ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}"
HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Focusable="False" Command="{Binding DataContext.DeletePatientCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<Image Source="Images/DeletePatient.png" />
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" IsReadOnly="True"
ItemsSource="{Binding DataContext.ReportNames,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
SelectedItem="{Binding DataContext.SelectedReportGroup,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
Margin="200,0,0,0" Width="500" HorizontalAlignment="Left">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}" Header="Report Name" Width="5*"
ElementStyle="{StaticResource VerticalCenter}"/>
<DataGridTemplateColumn Header="Delete" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Focusable="False" Command="{Binding DataContext.DeleteAllReportsOfATypeCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<Image Source="Images/DeleteReport.png" Height="48" Width="48" />
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" IsReadOnly="True"
ItemsSource="{Binding DataContext.CorrespondingDates,
RelativeSource={RelativeSource FindAncestor,
AncestorType=Window}}"
SelectedItem="{Binding DataContext.SelectedReport,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Width="390" HorizontalAlignment="Right">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Date" Width="5*"
HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringFormat='{}{0:dd/MM/yyyy}'}"
Tag="{Binding DataContext.Tag,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Style="{StaticResource VerticalAndHorizontalCenterTextBlock}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Edit" Width="1.5*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Focusable="False" Click="OpenTabForEdit"
Command="{Binding DataContext.EditSingleReportCommand,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<Image Source="Images/EditReport.png" Height="48" Width="48" />
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete" Width="1.5*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Focusable="False"
Command="{Binding DataContext.DeleteSingleReportCommand,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<Image Source="Images/DeleteReport.png" Height="48" Width="48"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Update 2 : The Class Structure
Similar for BloodChemistry and UrineAnalysis
It seems to me that you need a MultiBinding here, because you have two inputs: the entire collection, and the specific date you want to count. The XAML syntax would look something like this:
<TextBlock>
<TextBlock.Resources>
<my:ItemCountMultiConverter x:Key="ItemCountMultiConverter" />
</TextBlock.Resources>
<TextBlock.Tag>
<MultiBinding Converter="{StaticResource ItemCountMultiConverter}">
<Binding Path="." />
<Binding Path="ItemsSource" RelativeSource="{RelativeSource AncestorType=DataGrid}" />
</MultiBinding>
</TextBlock.Tag>
</TextBlock>
Then it is just a matter of implementing ItemCountMultiConverter : IMultiValueConverter to extract the date count from the collection:
public class ItemCountMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length < 2)
return DependencyProperty.UnsetValue;
var dateToCount = values[0] as DateTime?;
var source = values[1] as IEnumerable<Patient>;
if (!dateToCount.HasValue || source == null)
return DependencyProperty.UnsetValue;
source.Count(patient =>
patient.Haemogram.Any(haemogram => haemogram.Date == dateToCount)
|| patient.UrineAnalysis.Any(urine => urine.Date == dateToCount)
|| patient.BloodChemistry.Any(blood => blood.Date == dateToCount)
);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

Categories

Resources