My code:
<DataGrid HorizontalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderBrush="#83D744" IsSynchronizedWithCurrentItem="False" VerticalGridLinesBrush="Transparent" Grid.Column="0" RowHeaderWidth="0" CanUserAddRows="False" AutoGenerateColumns="False" x:Name="datagrid1" Margin="10,150,8,50" Background="Transparent" RowBackground="#FF494949" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#83D744"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="50"/>
</Style>
<Style x:Key="TextInCellCenter" TargetType="{x:Type TextBlock}" >
<Setter Property="TextAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="RightAligElementStyle">
<Setter Property="TextAlignment" Value="Right"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="LeftAligElementStyle">
<Setter Property="TextAlignment" Value="Left"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
</DataGrid.Resources>
<DataGrid.Columns >
<DataGridTextColumn Binding="{Binding ProductName}" ElementStyle="{StaticResource LeftAligElementStyle}" Header="NAZIV ARTIKLA" MinWidth="350" Foreground="White" FontSize="20" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding Quantity}" ElementStyle="{StaticResource TextInCellCenter}" Header="KOLIČINA" MinWidth="200" Foreground="White" FontSize="20" FontFamily="Verdana" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" Content="Finish Order" Margin="0,0,55,5" DockPanel.Dock="Right" Click="btnFinishOrder_Click" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush= "{TemplateBinding BorderBrush}"
Background= "{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="btnTakeIt_Click" Content="Take it" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Number of Order:# {0}}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
There you can see guys, when I click on button Click="btnTakeIt_Click" I programaticaly change buttons text to "Order in progress." and I update field in my database IsInProgres to 1 - true, code is here:
private void btnTakeIt_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
CollectionViewGroup group = b.DataContext as CollectionViewGroup;
var x = group.Name;
int orderNumber = Convert.ToInt32(x);
b.BorderBrush = null;
b.Content = "Order is in progress";
b.FontSize = 12;
OrdersController.SetOrderInProgressByID(orderNumber);
}
But what is happening, because I'm refreshing my grid every 20 seconds my button content is becoming again like it's on default "Take it!" because that's whats written in XAML.
Like this:
This is my code behind (refresh every few seconds):
public MainWindow()
{
try
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = ordersList;
collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = collectionViewSource;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(20);
timer.Tick += timer_Tick;
timer.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void timer_Tick(object sender, EventArgs e)
{
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = null;
collectionViewSource.Source = ordersList;
DataContext = collectionViewSource;
datagrid1.ScrollIntoView(datagrid1.Items[datagrid1.Items.Count - 1]);
}
}
So my question is could I somehow loop my localOrders and check if NumberOfOrder has IsInProgress = 1 and simply set this:
btnTakeIt.Content="Order in progress.."
So everytime my grid refresh I can loop my orders, and check is order InProgress and after that I can set button btnTakeIt content to "Order in progress.."
Or if there is any other way, I am opened to try it!
P.S I tried allready but my btnTakeIt is not accessible in code behind :(
EDIT:
void timer_Tick(object sender, EventArgs e)
{
Button MyButton = FindChild<Button>(datagrid1, "btnTakeIt");
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = null;
collectionViewSource.Source = ordersList;
foreach (var item in ordersList)
{
if (item.IsInProgress== true)
{
MyButton.Content = "Order is in progress";
}
}
DataContext = collectionViewSource;
}
Can I do it like this? I checked debuger and it is entering inside of if statement and when I look at breakpoint it acctualy changes content but on grid I can not see anything changed :(
EDIT:
I have to mention that my class Product is contained in my OrdersController :)
#Ayuman
what do you think about this:
<Button Name="btnTakeIt" DataContext="{Binding Items[0]}" Content="{Binding Status}"Click="btnTakeIt_Click" Content="Take it" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
code behind:
public static List<LocalOrders> localOrders()
{
var results = DataServices.POS.proc_GetAllOrders().ToList();
List<LocalOrders> localOrdersList = new List<LocalOrders>();
foreach (var item in results)
{
LocalOrders lokal = new LocalOrders();
if (item.IsInProgress)
{
localo.Pihvacena = true;
localo.Status = "IN PROCESS";
}
else
{
lokalne.Status = "IT IS NOT YET IN PROCESS";
}
lokal.User = item.User;
lokal.Quantity = Convert.ToInt32(item.Quantity);
lokal.Title = item.Title;
lokal.NumberOfOrder = item.NumberOfOrder;
localOrdersList.Add(lokal);
}
return localOrdersList;
}
So I can programaticaly check for status of order and set content of button like that.. is it good solution maybe?
Please refer below code. I tried to make it work. Hope this works for you as well
<DataGrid HorizontalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderBrush="#83D744" IsSynchronizedWithCurrentItem="False" VerticalGridLinesBrush="Transparent" Grid.Column="0" RowHeaderWidth="0" CanUserAddRows="False" AutoGenerateColumns="False" x:Name="datagrid1" Margin="10,150,8,50" Background="Transparent" RowBackground="#FF494949" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#83D744"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="50"/>
</Style>
<Style x:Key="TextInCellCenter" TargetType="{x:Type TextBlock}" >
<Setter Property="TextAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="RightAligElementStyle">
<Setter Property="TextAlignment" Value="Right"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="LeftAligElementStyle">
<Setter Property="TextAlignment" Value="Left"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
</DataGrid.Resources>
<DataGrid.Columns >
<DataGridTextColumn Binding="{Binding ProductName}" ElementStyle="{StaticResource LeftAligElementStyle}" Header="NAZIV ARTIKLA" MinWidth="350" Foreground="White" FontSize="20" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding Quantity}" ElementStyle="{StaticResource TextInCellCenter}" Header="KOLIČINA" MinWidth="200" Foreground="White" FontSize="20" FontFamily="Verdana" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" DataContext="{Binding Items[0]}" Content="{Binding ButtonCaption}" Margin="0,0,55,5" DockPanel.Dock="Right" Click="BtnFinishOrder_OnClick" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush= "{TemplateBinding BorderBrush}"
Background= "{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="BtnTakeIt_OnClick" DataContext="{Binding Items[0]}" Content="{Binding ButtonCaption}" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Items[0].ProductName}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
public partial class MainWindow : Window
{
private ICollectionView view;
private ObservableCollection<Product> ordersList;
public MainWindow()
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
ordersList = new ObservableCollection<Product>()
{
new Product()
{
ProductName = "Prodct",
Quantity = 1,
NumberOfOrder = 100,
IsInProgress = true,
ButtonCaption = "Take it"
},
new Product()
{
ProductName = "Prodct1",
Quantity = 2,
NumberOfOrder = 1000,
ButtonCaption = "Take it"
},
new Product()
{
ProductName = "Prodct2",
Quantity = 3,
NumberOfOrder = 10000,
ButtonCaption = "Take it"
},
new Product()
{
ProductName = "Prodct3",
Quantity = 4,
NumberOfOrder = 100000,
ButtonCaption = "Take it"
},
};
view = CollectionViewSource.GetDefaultView(ordersList);
view.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = view;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(20);
timer.Tick += Timer_Tick; ;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
foreach (var item in ordersList)
{
if (item.IsInProgress)
{
item.ButtonCaption = "Order is Still in progress";
}
}
}
private void BtnFinishOrder_OnClick(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
private void BtnTakeIt_OnClick(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
Product prod = b.DataContext as Product;
b.BorderBrush = null;
prod.ButtonCaption = "Order is in progress";
b.FontSize = 12;
}
}
class Product:INotifyPropertyChanged
{
private string productName;
public string ProductName
{
get { return productName ; }
set
{
productName = value ;
OnPropertyChanged("ProductName");
}
}
private int quantity;
public int Quantity
{
get { return quantity; }
set
{
quantity = value;
OnPropertyChanged("Quantity");
}
}
public int NumberOfOrder { get; set; }
public bool IsInProgress { get; set; }
private string buttonCaption;
public string ButtonCaption
{
get { return buttonCaption; }
set
{
buttonCaption = value;
OnPropertyChanged("ButtonCaption");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Related
i have a problem with the ToolTips and need some helping hand.
I want to create a custom design for all tooltips, adding a header and a footer.
Because it should be the default tooltip style/template i created attached properties, to set the values for header and footer on all UI elements.
public class ToolTipExtensions
{
public static readonly DependencyProperty HeaderProperty = DependencyProperty.RegisterAttached("Header",
typeof(string), typeof(ToolTipExtensions), new PropertyMetadata(null));
public static readonly DependencyProperty FooterProperty = DependencyProperty.RegisterAttached("Footer",
typeof(string), typeof(ToolTipExtensions), new PropertyMetadata(null));
public static void SetHeader(UIElement element, string value)
{
element.SetValue(HeaderProperty, value);
}
public static string GetHeader(UIElement element)
{
return (string)element.GetValue(HeaderProperty);
}
public static void SetFooter(UIElement element, string value)
{
element.SetValue(FooterProperty, value);
}
public static string GetFooter(UIElement element)
{
return (string)element.GetValue(FooterProperty);
}
}
Im using the following style.
<Style TargetType="{x:Type ToolTip}">
<Setter Property="MinHeight" Value="150" />
<Setter Property="Width" Value="350" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="#ECEFF4" />
<Setter Property="BorderBrush" Value="#394F6D" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,1">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
MinHeight="40"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ToolTipExtensions.Header)}"
FontFamily="Arial"
FontSize="13"
FontWeight="Bold"
Foreground="{TemplateBinding Foreground}" />
<TextBlock
Grid.Row="1"
MinHeight="40"
Foreground="{TemplateBinding Foreground}"
Text="{Binding ToolTip, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<Label
Grid.Row="2"
MinHeight="30"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ToolTipExtensions.Footer)}"
FontFamily="Arial"
FontSize="12"
FontStyle="Italic"
FontWeight="Regular" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Im doing something wrong, because the tooltip dosent show anything. No ToolTip, no Header, no Footer.
Whats the problem with it? Wrong DataContext for the ToolTip?
Heres the usage:
<Button
local:ToolTipExtensions.Header="Button"
local:ToolTipExtensions.Footer="To show additional Info"
Content="Test"
ToolTip="Some fancy Text"
ToolTipService.InitialShowDelay="500"
ToolTipService.ShowDuration="999999999" />
Regards,
SyLuS
ToolTip for every control will be updated
Modified Style
<VM:DependecnyObjectTypeConverter x:Key="ConverterPa"/>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="MinHeight" Value="150" />
<Setter Property="Width" Value="350" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="#ECEFF4" />
<Setter Property="BorderBrush" Value="#394F6D" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,1">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
MinHeight="40"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource ConverterPa},ConverterParameter=Header}"
FontFamily="Arial"
FontSize="13"
FontWeight="Bold"
Foreground="{TemplateBinding Foreground}" />
<TextBlock
Grid.Row="1"
MinHeight="40"
Foreground="{TemplateBinding Foreground}"
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource ConverterPa},ConverterParameter=ToolTip}"/>
<Label
Grid.Row="2"
MinHeight="30"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource ConverterPa},ConverterParameter=Footer}"
FontFamily="Arial"
FontSize="12"
FontStyle="Italic"
FontWeight="Regular" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
IValueConverter:
public class DependecnyObjectTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var plTarget = value as System.Windows.Controls.ToolTip;
if (parameter.ToString() == "Header")
{
return plTarget.PlacementTarget.GetValue(ToolTipExtensions.HeaderProperty);
}
if (parameter.ToString() == "ToolTip")
{
return plTarget.PlacementTarget.GetValue(Control.ToolTipProperty);
}
if (parameter.ToString() == "Footer")
{
return plTarget.PlacementTarget.GetValue(ToolTipExtensions.HeaderProperty);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<Grid>
<Grid x:Name="thumbGrid" ShowGridLines="True" ClipToBounds="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=ThumbSelectorLeftMargin, Mode=TwoWay}"/>
<ColumnDefinition Width="{Binding Path=ThumbWidthSelector, Mode=TwoWay}"/>
<ColumnDefinition Width="{Binding Path=ThumbSelectorRightMargin, Mode=TwoWay}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding Path=ThumbSelectorTopMargin, Mode=TwoWay}" />
<RowDefinition Height="{Binding Path=ThumbHeightSelector, Mode=TwoWay}"/>
<RowDefinition Height="{Binding Path=ThumbSelectorBottomMargin, Mode=TwoWay}"/>
</Grid.RowDefinitions>
<GridSplitter Grid.Column="0" Grid.RowSpan="3" HorizontalAlignment="Right" BorderBrush="Transparent"
BorderThickness="2" ShowsPreview="True" DragCompleted="ThumbLeftGridSplitterDragCompleted" />
<GridSplitter Grid.Column="2" Grid.RowSpan="3" HorizontalAlignment="Left" BorderBrush="Transparent"
BorderThickness="2" ShowsPreview="True" DragCompleted="ThumbRightGridSplitterDragCompleted" />
<Grid x:Name="thumbImgGrid" MouseDown="thumbImgGrid_MouseDown" MouseMove="thumbImgGrid_MouseMove" MouseUp="thumbImgGrid_MouseUp" Grid.Row="1" Grid.Column="1">
<Border x:Name="thumbBorder">
<Image Stretch="Fill"/>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ThumbBackgroundEntity.FillType}" Value="Color">
<Setter Property="Background" Value="{Binding Path=ThumbBackgroundEntity.BackgroundColor , Mode=TwoWay}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ThumbBackgroundEntity.FillType}" Value="NoFill">
<Setter Property="Background" Value="{Binding Path=ThumbBackgroundEntity.BackgroundColor , Mode=TwoWay}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Opacity="{Binding Path=ThumbBackgroundEntity.Opacity , Mode=TwoWay}">
<Image x:Name="thumbImage" Source="{Binding Path=ThumbBackgroundEntity.BackgroundImageFullPath , Mode=TwoWay, Converter={StaticResource StringToImgConverter}}"
RenderTransformOrigin="0.5, 0.5" Stretch="Fill">
<Image.LayoutTransform>
<RotateTransform Angle="{Binding Path=ThumbBackgroundEntity.ImageAngle , Mode=TwoWay}"/>
</Image.LayoutTransform>
</Image>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ThumbBackgroundEntity.FillType}" Value="Color">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ThumbBackgroundEntity.FillType}" Value="NoFill">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Grid>
<GridSplitter Grid.Row="0" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" BorderBrush="Transparent" BorderThickness="2" ShowsPreview="True"/>
<GridSplitter Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Top" BorderBrush="Transparent" BorderThickness="2" ShowsPreview="True" />
</Grid>
</Grid>
I want to move thumbImgGrid inside grid keeping height and width constant(maintain image aspect ratio)
I did following way but i could not maintain the height and width same on move.
On mouse down i calculated top left value of thumbImgGrid
private void thumbImgGrid_MouseDown(object sender, MouseButtonEventArgs e)
{
startTopLeft = thumbImgGrid.TranslatePoint(new Point(0, 0), trackGrid);
startRightBottom = new Point(startTopLeft.X + thumbImgGrid.ActualWidth, startTopLeft.Y + thumbImgGrid.ActualHeight);
thumbImgGrid.CaptureMouse();
}
Mouse move function,here i get the current thumbGrid position and get the difference of points with old and new position and difference is added or subtracted in old value.
private void thumbImgGrid_MouseMove(object sender, MouseEventArgs e)
{
if (thumbImgGrid.IsMouseCaptured)
{
Vector offset = Point.Subtract(e.GetPosition(thumbGrid), startTopLeft);
double newLeft = startTopLeft.X + offset.X;
double NewTop = startTopLeft.Y + offset.Y;
Point newRightBottom = new Point(newLeft + thumbImgGrid.ActualWidth, newLeft+ thumbImgGrid.ActualHeight);
//thumbImgGrid.Margin = new Thickness(newLeft, NewTop, newRightBottom.X, newRightBottom.Y);
_DataSource.ThumbSelectorLeftMargin = new GridLength(newLeft, GridUnitType.Star);
//_DataSource.ThumbWidthSelector = new GridLength(thumbImgGrid.ActualWidth, GridUnitType.Star);
//_DataSource.ThumbSelectorRightMargin = new GridLength(newLeft + thumbImgGrid.ActualWidth, GridUnitType.Star);
_DataSource.ThumbSelectorTopMargin = new GridLength(NewTop, GridUnitType.Star);
//_DataSource.ThumbHeightSelector = new GridLength(thumbImgGrid.ActualHeight, GridUnitType.Star);
// _DataSource.ThumbSelectorBottomMargin = new GridLength(newLeft + thumbImgGrid.ActualHeight, GridUnitType.Star);
_DataSource.UpdateThumbDimnsionLayout();
}
}
Mouse Up Function
private void thumbImgGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
thumbImgGrid.ReleaseMouseCapture();
}
I am unable to maintain the height width constant on mouse move.
Thanks in advance.
I am trying to create a generic page navigation button using a Style and ControlTemplate. The idea is that the destination page is the CommandParameter of the button:
<Button Height="64" Width="64" Style="{DynamicResource ButtonViewTileStyle}"
Command="{Binding Path=ChangePage}"
CommandParameter="{Binding Path=HomePage}"/>
...and every page has a DisplayName and IconName property that I would like to use to use in the ControlTemplate. Here is a non-working example with just the display name:
<Style x:Key="ButtonViewTileStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Canvas>
<TextBlock TextWrapping="Wrap"
Text="{Binding CommandParameter.DisplayName,
RelativeSource={RelativeSource TemplatedParent}}"
Canvas.Left="0" Canvas.Top="0"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any suggestions on what the Text= binding should be to make this work?
Please refer the below code.
<Window.Resources>
<Style x:Key="ButtonViewTileStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Canvas>
<TextBlock TextWrapping="Wrap"
Text="{Binding CommandParameter.DisplayName,
RelativeSource={RelativeSource TemplatedParent}}"
Canvas.Left="0" Canvas.Top="0"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Command="{Binding TestCommand}" Width="100" Height="25" Style="{DynamicResource ButtonViewTileStyle}" CommandParameter="{Binding Path=PageDetails}"></Button>
</StackPanel>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new TestViewModel();
}
}
class TestViewModel
{
private CommndPrm pageDetials;
public CommndPrm PageDetails
{
get { return pageDetials; }
set { pageDetials = value; }
}
public TestViewModel()
{
pageDetials = new CommndPrm() { DisplayName="Test"};
}
}
class CommndPrm
{
private string displayName;
public string DisplayName
{
get { return displayName; }
set { displayName = value; }
}
}
I am just wondering if there is a wpf combobox control that can contain multiple columns?
And if not, what XAML I need to use to achieve this?
I am just looking for a basic two column combobox if is possible,
Thanks
Please Refer these links for Multiple Column Combobox which is implemented by editing combox and comboboxitem Default template/style.
1)Link1
2)Link2
Xaml code : Please take a look at commented Trigger IsHighlighted in ComboboxItem style
<Grid>
<ComboBox Height="30" Margin="5" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="2" Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid x:Name="gd" TextElement.Foreground="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Margin="5" Grid.Column="1" Text="{Binding State}"/>
<TextBlock Margin="5" Grid.Column="2" Text="{Binding Population}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ComboBoxItem.IsSelected" Value="True">
<Setter TargetName="gd" Property="Background" Value="Gray"></Setter>
<Setter TargetName="gd" Property="TextElement.Foreground" Value="White"></Setter>
</Trigger>
<Trigger Property="ComboBoxItem.IsMouseOver" Value="True">
<Setter TargetName="gd" Property="Background" Value="Blue"></Setter>
<Setter TargetName="gd" Property="TextElement.Foreground" Value="White"></Setter>
</Trigger>
<!--IsHighlighted and IsMouseOver is showing same effect but IsHighlighted is used for showing logical focus( for understanding check using tab key)-->
<!--<Trigger Property="ComboBoxItem.IsHighlighted" Value="True">
<Setter TargetName="gd" Property="Background" Value="Yellow"></Setter>
<Setter TargetName="gd" Property="TextElement.Foreground" Value="Black"></Setter>
</Trigger>-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
</Grid>
c# code
public partial class MainWindow : Window
{
private ObservableCollection<City> cities = new ObservableCollection<City>();
public MainWindow()
{
InitializeComponent();
cities.Add(new City() { Name = "Mumbai", State = "Maharashtra", Population = 3000000 });
cities.Add(new City() { Name = "Pune", State = "Maharashtra", Population = 7000000 });
cities.Add(new City() { Name = "Nashik", State = "Maharashtra", Population = 65000 });
cities.Add(new City() { Name = "Aurangabad", State = "Maharashtra", Population = 5000000 });
DataContext = cities;
}
}
class City
{
public string State { get; set; }
public string Name { get; set; }
public int Population { get; set; }
}
Output
Because I found, Heena, that your Xaml does not provide selected dropped down items to be highlighted I modified your code as follows:
Xaml
<ComboBox Name="cbCities" Height="30" Margin="5" HorizontalContentAlignment="Left" HorizontalAlignment="Stretch" ItemsSource="{Binding}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="2" Text="{Binding Name}"/>
<TextBlock Margin="2" Text="{Binding State}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="templateBorder" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter>
<ContentPresenter.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Margin="5" Grid.Column="1" Text="{Binding State}"/>
<TextBlock Margin="5" Grid.Column="2" Text="{Binding Population}"/>
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
<Setter TargetName="templateBorder" Property="Background" Value="{x:Static SystemColors.HighlightBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
C#
private void Window_Loaded(object sender, RoutedEventArgs e)
{
cities.Add(new City() { Name = "Boston", State = "MA", Population = 3000000 });
cities.Add(new City() { Name = "Los Angeles", State = "CA", Population = 7000000 });
cities.Add(new City() { Name = "Frederick", State = "MD", Population = 65000 });
cities.Add(new City() { Name = "Houston", State = "TX", Population = 5000000 });
cbCities.DataContext = cities;
}
class City
{
public string State { get; set; }
public string Name { get; set; }
public int Population { get; set; }
}
Output
I know im late but this is how you do it in a simplified way, After the DataTemplate tag you can put anything depending on how you want your lay out to look like.
<ComboBox.ItemTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{StaticResource ForegroundMainBrush}"
Margin="5 0"
FontFamily="{StaticResource LatoBold}"
VerticalAlignment="Center">
<Run Text="Code :" />
<Run Text="{Binding ActivityCode,Mode=OneWay}" />
</TextBlock>
<TextBlock Foreground="{StaticResource ForegroundDarkBrush}"
Margin="5 0"
Text="|"
FontFamily="{StaticResource LatoBold}"
VerticalAlignment="Center" />
<TextBlock Foreground="{StaticResource ForegroundMainBrush}"
Margin="5 0"
FontFamily="{StaticResource LatoBold}"
VerticalAlignment="Center">
<Run Text="Rate :" />
<Run Text="{Binding Rate,Mode=OneWay}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
Result
Sample Result
Or Use a readonly property in your DataModel as shown on the code below and set your combobox DisplayMemberPath to DisplayMemberPath="CodeRate"
public string ActivityCode { get; set; }
public string Rate { get; set; }
public string CodeRate => string.Format("Code: {0} | Rate:
{1}",ActivityCode,Rate);
I just use StackPanels in mine. Maybe kind of redundant per item, but it got me exactly the solution I wanted without getting too deep into things.
<ComboBox Name="cboTask">
<StackPanel Orientation="Horizontal">
<ComboBoxItem Name="someTask" Content="Doing Some Task" /><Button Name="cmdDetails" Content="..." />
</StackPanel>
</ComboBox>
I have a datagrid in my form which has columns for each of Question Types.
I want that column to be split into two as i want to accept number of compulsory and number of optional questions for each of the question type in the subsequent columns.
I have achieved this in winforms, thanks to stackoverflow.com.
I am trying to achieve the same in WPF
Thanks in advance
I guess this is the DataGrid layout you want.... right?
.------.-----------------.--------.
| | ID Details | |
| Name |-----------------| Status |
| | ID | Passport | |
|------|------|----------|--------|
|X | 123 | E567868 | Present|
|Y | 236 | 7875678 | Absent |
'------'------'----------'--------'
WPF datagrid doesnt support this readily. But you can do some stretchy coding. The code like below can split the headers. You need to take caution that ...
When the split columns are reordered (DataGrid.ColumnReordered
event), all the sibling columns under their common parent header should be
moved, together. I am leaving that code to you.
Have some custom styles for DataGridHeaders
<Style TargetType="{x:Type Primitives:DataGridColumnHeader}"
x:Key="SplitHeaderStyle">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Primitives:DataGridColumnHeader}">
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Bottom">
<Controls:DataGridHeaderBorder
SortDirection="{TemplateBinding SortDirection}"
IsHovered="{TemplateBinding IsMouseOver}"
IsPressed="{TemplateBinding IsPressed}"
IsClickable="{TemplateBinding CanUserSort}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding ="{TemplateBinding Padding}"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
SeparatorBrush="{TemplateBinding SeparatorBrush}">
<ContentPresenter
Content="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Content[0]}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="Center"/>
</Controls:DataGridHeaderBorder>
<Thumb x:Name="PART_LeftHeaderGripper"
HorizontalAlignment="Left"
Style="{StaticResource ColumnHeaderGripperStyle}"/>
<Thumb x:Name="PART_RightHeaderGripper"
HorizontalAlignment="Right"
Style="{StaticResource ColumnHeaderGripperStyle}"/>
</Grid>
<Grid DockPanel.Dock="Top">
<Controls:DataGridHeaderBorder
HorizontalAlignment="Stretch"
IsClickable="False"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding SeparatorBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding ="{TemplateBinding Padding}"
SeparatorVisibility="{TemplateBinding Tag}"
SeparatorBrush="{TemplateBinding SeparatorBrush}">
<ContentPresenter
Content="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Content[1]}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="-8,2,-10,2"/>
</Controls:DataGridHeaderBorder>
<Thumb x:Name="PART_LeftSplitHeaderGripper"
HorizontalAlignment="Right"
Visibility="{TemplateBinding Tag}"
Style="{StaticResource ColumnHeaderGripperStyle}"/>
</Grid>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Primitives:DataGridColumnHeader}"
BasedOn="{StaticResource SplitHeaderStyle}"
x:Key="SplitHeaderLeftStyle">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Tag" Value="{x:Static Visibility.Visible}"/>
</Style>
<Style TargetType="{x:Type Primitives:DataGridColumnHeader}"
BasedOn="{StaticResource SplitHeaderStyle}"
x:Key="SplitHeaderRightStyle">
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="Tag" Value="{x:Static Visibility.Collapsed}"/>
</Style>
Have columns arranged like this...
<Controls:DataGrid.Columns>
<Controls:DataGridTextColumn
Header="Name"
Binding="{Binding Name}"/>
<Controls:DataGridTextColumn
Binding="{Binding ID}"
HeaderStyle="{StaticResource SplitHeaderRightStyle}">
<Controls:DataGridTextColumn.Header>
<x:ArrayExtension Type="System:String">
<System:String>ID</System:String>
<System:String>ID De</System:String>
</x:ArrayExtension>
</Controls:DataGridTextColumn.Header>
</Controls:DataGridTextColumn>
<Controls:DataGridTextColumn
Binding="{Binding Passport}"
HeaderStyle="{StaticResource SplitHeaderLeftStyle}">
<Controls:DataGridTextColumn.Header>
<x:ArrayExtension Type="System:String">
<System:String>Passport</System:String>
<System:String>tails</System:String>
</x:ArrayExtension>
</Controls:DataGridTextColumn.Header>
</Controls:DataGridTextColumn>
<Controls:DataGridTextColumn
Header="Status"
Binding="{Binding Status}"/>
</Controls:DataGrid.Columns>
So basically you use the same default header layout of DataGrid but hack it in a way that two headers look like they are joined together.
C#
Name your DataGrid e.g. x:Name="MyDataGrid".
Keep all the styles in XAML in <DataGrid.Resources ..> tag. Make sure that they have x:Key set. e.g. x:Key="SplitHeaderLeftStyle" & x:Key="SplitHeaderRightStyle"
<DataGrid x:Name="MyDataGrid">
<DataGrid.Resources>
<Style
TargetType="{x:Type Primitives:DataGridColumnHeader}"
x:Key="SplitHeaderStyle" .../>
<Style x:Key="SplitHeaderLeftStyle"
BasedOn="{StaticResource SplitHeaderStyle}".../>
<Style x:Key="SplitHeaderRightStyle"
BasedOn="{StaticResource SplitHeaderStyle}" .../>
</DataGrid.Resources>
...
</DataGrid>
in your C# code when you add columns, set the styles by their Key.
var dgIDColumn
= new DataGridTextColumn()
{
Header = new string[] { "ID", "ID Det" },
Binding = new Binding() { Path = new PropertyPath("ID") },
HeaderStyle = MyDataGrid.FindResource("SplitHeaderRightStyle") as Style;
};
MyDataGrid.Columns.Add(dgIDColumn);
var dgPassportColumn
= new DataGridTextColumn()
{
Header = new string[] { "Passport", "ails" },
Binding = new Binding() { Path = new PropertyPath("Passport") },
HeaderStyle = MyDataGrid.FindResource("SplitHeaderLeftStyle") as Style;
};
MyDataGrid.Columns.Add(dgPassportColumn);
<DataGrid ItemsSource="{Binding PeopleList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="10"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Question1" Grid.ColumnSpan="2"/>
<TextBlock Text="Compulsory" Grid.Row="1"/>
<TextBlock Text="Optional Q" Grid.Row="1" Grid.Column="2"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:Person}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="65"/>
<ColumnDefinition/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Question.Col1}"/>
<TextBlock Text="{Binding Question.Col2}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
You can modify the Row/Column/ColumnSpan/RowSpan in DataTriggers of ItemsControl.ItemContainerStyle to your liking.
<ItemsControl ItemsSource="{Binding Path=Cells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid
local:GridHelpers.ColumnCount="{Binding NumOfColumns}"
local:GridHelpers.AutoColumns="0,1"
local:GridHelpers.RowCount="{Binding NumOfRows}"
local:GridHelpers.AutoRows="0,1">
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Path=RowIndex}"/>
<Setter Property="Grid.Column" Value="{Binding Path=ColumnIndex}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CellType}" Value="BaseCell">
<Setter Property="ContentTemplate" Value="{StaticResource BaseCell}"/>
<Setter Property="Grid.ColumnSpan" Value="{Binding Path=ColumnSpan}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=CellType}" Value="CornerHeader">
<Setter Property="ContentTemplate" Value="{StaticResource CornerHeader}"/>
<Setter Property="Grid.RowSpan" Value="2"/>
<Setter Property="Grid.ColumnSpan" Value="2"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=CellType}" Value="PersonNameCell">
<Setter Property="ContentTemplate" Value="{StaticResource PersonNameCell}"/>
</DataTrigger>
...
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
I've added AutoColumns property to GridHelper class which is explained in this link
#region AutoColumns Property
/// <summary>
/// Makes the specified Column's Width equal to Auto.
/// Can set on multiple Columns
/// </summary>
public static readonly DependencyProperty AutoColumnsProperty =
DependencyProperty.RegisterAttached(
"AutoColumns", typeof(string), typeof(GridHelpers),
new PropertyMetadata(string.Empty, AutoColumnsChanged));
// Get
public static string GetAutoColumns(DependencyObject obj)
{
return (string)obj.GetValue(AutoColumnsProperty);
}
// Set
public static void SetAutoColumns(DependencyObject obj, string value)
{
obj.SetValue(AutoColumnsProperty, value);
}
// Change Event - Makes specified Column's Width equal to Auto
public static void AutoColumnsChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
return;
SetAutoColumns((Grid)obj);
}
private static void SetAutoColumns(Grid grid)
{
string[] autoColumns = GetAutoColumns(grid).Split(',');
for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
{
if (autoColumns.Contains(i.ToString()))
grid.ColumnDefinitions[i].Width = GridLength.Auto;
}
}
private static void SetAutoRows(Grid grid)
{
string[] autoRows = GetAutoRows(grid).Split(',');
for (int i = 0; i < grid.RowDefinitions.Count; i++)
{
if (autoRows.Contains(i.ToString()))
grid.RowDefinitions[i].Height = GridLength.Auto;
}
}
#endregion