How to add tooltip text on my Gridview column header, WPF VS2010 - wpf

Here is my grid i what to give an explanation to the header "RED.BROJ" when on mouse over that header to show the expl. text.
<ListView.View>
<GridView>
<GridViewColumn Width="50"
Header="Реd.Број"
DisplayMemberBinding="{Binding Path=RedenBroj}">
</GridViewColumn>

You could do this:
<GridViewColumn Width="50"
DisplayMemberBinding="{Binding Path=RedenBroj}">
<GridViewColumn.Header>
<TextBlock Text="Ред.Број"
ToolTip="Your explanation" />
</GridViewColumn.Header>
</GridViewColumn>

Slightly late response but you can add a tooltip, without losing the ability to drag columns to reorder them, by doing the following:
<GridViewColumn Width="50"
Header="Реd.Број"
DisplayMemberBinding="{Binding Path=RedenBroj}">
<GridViewColumn.HeaderContainerStyle>
<Style>
<Setter Property="Control.ToolTip" Value="Tool tip content"/>
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
Update: more concise version thanks to LPL
Further update: I wanted to be able to have all columns have tooltips that match their headers (as some columns were too narrow to show the whole header):
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<Setter Property="ToolTip"
Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn DisplayMemberBinding="{Binding A}" Header="A"/>
<GridViewColumn DisplayMemberBinding="{Binding B}" Header="B"/>
<GridViewColumn DisplayMemberBinding="{Binding C}" Header="C"/>
</GridView>
</ListView>

Nothing like answering an old question with your own...
I was inspired by #Scroog1's answer but seems a bit redundant having a Tooltip which just mimics the content that is there. You usually want the Tooltip because you've abbreviated the column header text.
I created a small AttachedProperty which I set my Tooltip value on the GridViewColumn. I then bind to this from my Style for my GridViewColumnHeader.
Now I just define the Style once, and add it and the AttachedProperty where I want to use it.
Xaml
<Style x:Key="GridViewColumnHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="ToolTip" Value="{Binding Path=Column.(attachedProperties:GridViewColumnHeaderToolTipAttachedProperty.Tooltip), RelativeSource={RelativeSource Self}}" />
</Style>
<GridView x:Key="GridViewFuelConsumption"
x:Shared="False">
<GridViewColumn Header="Ред.Број"
DisplayMemberBinding="{Binding RedenBroj}"
HeaderContainerStyle="{StaticResource GridViewColumnHeaderStyle}"
attachedProperties:GridViewColumnHeaderToolTipAttachedProperty.Tooltip="Your explanation" />
</GridView>
AttachedProperty
public sealed class GridViewColumnHeaderToolTipAttachedProperty : DependencyObject
{
public static readonly DependencyProperty TooltipSourceProperty = DependencyProperty.RegisterAttached(
"Tooltip",
typeof(string),
typeof(GridViewColumnHeaderToolTipAttachedProperty),
new PropertyMetadata("null"));
public static void SetTooltip(DependencyObject element, string value)
{
element.SetValue(TooltipSourceProperty, value);
}
public static string GetTooltip(DependencyObject element)
{
return (string)element.GetValue(TooltipSourceProperty);
}
}

Related

How to get current cell value in GridView binding

Having spent the last few hours with this rather simple problem, I haven't yet found a way to do it. I'm using a GridView to display some data and need to perform some customization of the cell values using a converter. Here is the relevant XAML:
<ListView ItemsSource="{Binding SomeDataTable}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=XXX, Converter={StaticResource MyConverter}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
What do I need to write in place of XXX above?
N.B. I cannot put constant column name here because this DataTemplate is to be used by all columns of GridView. I need a way to refer to current cell value just like how GridView's default template works when using DisplayMemberBinding.
I found a relevant post here, but that also doesn't have any working answer.
One option is to use DisplayMemberBinding to create the GridViewColumns and then to define your TextBlock's style as a resource of your ListView and to use a converter there.
Given a scenario where I have a list of persons and I want to color all the cells based on the person's age:
Data item:
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
public Person(int age, string name)
{
Age = age;
Name = name;
}
}
Creating the columns in XAML:
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Age}" />
<GridViewColumn DisplayMemberBinding="{Binding Name}" />
</GridView>
</ListView.View>
The converter which changes cell background based on the age:
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((int) value < 20)
{
return Brushes.LightBlue;
}
return Brushes.LightGreen;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
Using the converter:
<ListView.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Background">
<Setter.Value>
<Binding Path="Age">
<Binding.Converter>
<local:MyConverter/>
</Binding.Converter>
</Binding>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
Result:
Full XAML:
<ListView x:Name="MyItems" Loaded="MyItems_OnLoaded">
<ListView.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Background">
<Setter.Value>
<Binding Path="Age">
<Binding.Converter>
<local:MyConverter/>
</Binding.Converter>
</Binding>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Age}" />
<GridViewColumn DisplayMemberBinding="{Binding Name}" />
</GridView>
</ListView.View>
</ListView>

Trying to do same thing with Listview/Gridview as I'm doing with DataGrid

guys!
I currently have this WPF Project With WCF and LINQ :
MainWindow.xaml
<GroupBox Header="Available Rooms" >
<DataGrid Name="roomDataGrid" ItemsSource="{Binding Rooms}" AutoGenerateColumns ="False" ">
<DataGrid.Columns>
<DataGridTextColumn Header="Room" Binding="{Binding RoomId}" />
<DataGridTextColumn Header="Reserved" Binding="{Binding RoomTaken}" />
<DataGridTextColumn Header="Beds" Binding="{Binding Beds}" />
<DataGridTextColumn Header="Size" Binding="{Binding Size}" />
<DataGridTextColumn Header="Rank" Binding="{Binding RoomRank}" />
</DataGrid.Columns>
</DataGrid>
</GroupBox>
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
viewModel = new ViewModel();
this.DataContext = viewModel;
}
ViewModel.cs
public class ViewModel
{
HotelService.HotelServiceClient hotelServiceClient = new HotelService.HotelServiceClient();
public List<RoomModel> Rooms
{
get
{
return hotelServiceClient.GetRooms().ToList();
}
}
}
So as you guys can see, I just set this.DataContext = viewModel and almost through sheer Magic, the WPF shows the database list of Rooms.
But my question is as following. Is there anyway I can achieve the same thing using a GridView/Listview ? I tried replacing the xaml with those Objects, but then it didn't show anything in the window.
Bonus question : Is there anyway to use GridView/ListView in accordance with events/delegates, so that I can save Rooms to DB and get the view updated, and also get the view updated when there are changes done to the DB that are not caused by this WPF?
I hope I supplied enough information! And thanks in advance :)
Try this:
<GroupBox Header="Available Rooms" >
<ListView Name="roomDataGrid" ItemsSource="{Binding Rooms}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Room" DisplayMemberBinding="{Binding RoomId}" />
<GridViewColumn Header="Reserved" DisplayMemberBinding="{Binding RoomTaken}" />
<GridViewColumn Header="Beds" DisplayMemberBinding="{Binding Beds}" />
<GridViewColumn Header="Size" DisplayMemberBinding="{Binding Size}" />
<GridViewColumn Header="Rank" DisplayMemberBinding="{Binding RoomRank}" />
</GridView>
</ListView.View>
</ListView>

Localize currency values in WPF GridView with different cultures for each row based on XAML bindings to culture name property

First time poster here but have been reading SO for ages and finally have run into a question that I've not been able to answer.
I've got a ListView hosting a GridView with multiple columns. One displays a price and another displays a currency code (CAD, USD, GBP, etc). This is all pulled out of SQL server using Entity Framework so the GridView is databound to a IEnumerable which stores the result of my query. The currency code is stored in a separate table with a localization string (en-US, en-GB) which (in a WinForms version of this app) was previously used in String.Format() to localize the currency to display the appropriate currency format and symbol.
The problem I have is in XAML binding the ConverterCulture of the Price binding to the Currency.LocalizedCultureName to get it to format correctly. Here's my current XAML:
<ListView Grid.Column="0" Name="pricingListingListView" ItemsSource="{Binding Source={StaticResource pricesByYear}}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Name}" Margin="0,0,0,10">
<ItemsPresenter/>
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Date" DisplayMemberBinding="{Binding Source.Date}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price" DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Currency" DisplayMemberBinding="{Binding Currency.Code}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Unit" DisplayMemberBinding="{Binding Unit.Name}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Source" DisplayMemberBinding="{Binding Source.Name}" Width="125" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Project" DisplayMemberBinding="{Binding Project.Description}" Width="125" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Plant Type" DisplayMemberBinding="{Binding Project.Plant.Name}" Width="100" />
</GridView>
</ListView.View>
</ListView>
PricesByYear is simply a CollectionViewSource which pulls the IEnumerable out of a DP in my code behind. The data is pulled out correctly, just not formatted.
This compiles fine, but generates a XamlParseException when I load the window containing it: A 'Binding' cannot be set on the 'ConverterCulture' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
The line generating the error is: <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price" DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}" Width="60" />
The short-form objective is to display the price, but format it according to the culture name stored as a string value. Each row in the gridview could potentially be different. As it seems I cannot bind within a binding, is there an alternative way I could go about this?
Answer
Multibinding did the trick, here's the working XAML:
<local:LocalizeCurrencyMultiConverter x:Key="localizeCurrencyMultiConverter"/>
...
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price" Width="60">
<!--DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}"-->
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource localizeCurrencyMultiConverter}">
<Binding Path="Price"/>
<Binding Path="Currency.LocalizedCultureName"/>
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
And the converter class:
public class LocalizeCurrencyMultiConverter :System.Windows.Data.IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
string localizedCurrency;
if (!values.Any() || values[0] == null)
throw new ArgumentException("Convert requires a minimum a price to display, and optionally a culture.");
double originalCurrency;
if (!double.TryParse(values[0].ToString(), out originalCurrency))
return values[0];
string localization = (values[1] ?? "en-CA").ToString();
try {
localizedCurrency = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture(localization), "{0:c}", originalCurrency);
} catch {
localizedCurrency = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture("en-CA"), "{0:c}", originalCurrency);
}
return localizedCurrency;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
return null;
}
}
Works like a charm.
Use a MultiBinding with a binding to the Price property and a binding the Culture property,
Write a MultiValueConverter and use the values to output the string you want.
I am going to make it easy for you:
MSDN MultiBinding
MSDN MultiConverter

How apply MinWidth for ListView columns in WPF in control template?

Following the answer to a similar question here, I was able to set the MinWidth on the XAML page.
What I would like to do is accomplish this in the control template for all GridViewColumn's in all ListView's.
Is this possible?
Update:
I tried a simple bit of sample code below, but it does not work:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}" >
<Setter Property="MinWidth" Value="200" />
</Style>
</Window.Resources>
<Grid Width="500">
<Border BorderBrush="Black" BorderThickness="2" Margin="20">
<ListView SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Header="Header 1" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="Hello There"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Header 2" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</Border>
</Grid>
</Window>
If you use a GridViewColumnHeader you can handle size changes:
<GridView>
<GridViewColumn>
<GridViewColumnHeader Content="HeaderContent" SizeChanged="HandleColumnHeaderSizeChanged"/>
...
in Code:
private void HandleColumnHeaderSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
{
if (sizeChangedEventArgs.NewSize.Width <= 60) {
sizeChangedEventArgs.Handled = true;
((GridViewColumnHeader) sender).Column.Width = 60;
}
}
<ListView>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock MinWidth="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...more columns...
</GridView>
</ListView.View>
</ListView>
<Window.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}" >
<Setter Property="MinWidth" Value="400" />
</Style>
</Window.Resources>
I stumbled into this one also. To solved it I had to do two things :
Modify the ControlTemplate of ListView's header.
Handle the DragDelta event of the Thumb inside the ControlTemplate.
ListView's header is GridViewColumnHeader.
Shown below is a simplified version of GridViewColumnHeader's ControlTemplate. As we can see, it uses a Thumb in a Canvas to create the drag/resize effect.
PS: To obtain the complete GridViewColumnHeader ControlTemplate please refer to How to grab WPF 4.0 control default templates?
<ControlTemplate TargetType="GridViewColumnHeader">
<Grid SnapsToDevicePixels="True">
<Border BorderThickness="0,1,0,1" Name="HeaderBorder" ...>
<!-- omitted -->
</Border>
<Border BorderThickness="1,0,1,1" Name="HeaderHoverBorder" Margin="1,1,0,0" />
<Border BorderThickness="1,1,1,0" Name="HeaderPressBorder" Margin="1,0,0,1" />
<Canvas>
<Thumb Name="PART_HeaderGripper">
<!-- omitted -->
</Thumb>
</Canvas>
</Grid>
<ControlTemplate.Triggers>
<!-- omitted -->
</ControlTemplate.Triggers>
So In order to limit the size of GridViewColumnHeader, we need to hook Thumb's drag events(DragStarted, DragDelta, DragCompleted...etc).
Turned out all we need is the DragDelta event as long we can know the MinSize within the DragDeltaEventHandler.
Shown below is modified XAML with comment.
<Grid Width="500">
<Border BorderBrush="Black" BorderThickness="2" Margin="20">
<ListView SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Header="Header 1" Width="Auto">
<!-- Apply a style targeting GridViewColumnHeader with MinWidth = 80 and a ControlTemplate -->
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="MinWidth" Value="80" />
<Setter Property="Control.Template" Value="{DynamicResource myGridViewColumnHeaderControlTemplate}" />
</Style>
</GridViewColumn.HeaderContainerStyle>**
</GridViewColumn>
<GridViewColumn Header="Header 2" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</Border>
</Grid>
In the myGridViewColumnHeaderControlTemplate add some XAML to:
Bind GridViewColumnHeader's MinWidth to Canvas's MinWidth.
Hook up Thumb's DragDelta event.
<ControlTemplate x:Key="TemplateGridViewColumnHeader" TargetType="GridViewColumnHeader">
<!-- omitted -->
<Canvas MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MinWidth, Mode=OneTime}">
<Thumb x:Name="PART_HeaderGripper" DragDelta="myGridViewColumnHeader_DragDelta">
Finally the myGridViewColumnHeader_DragDelta function:
private void myGridViewColumnHeader_DragDelta(object sender, DragDeltaEventArgs e)
{
DependencyObject parent = sender as DependencyObject;
try
{
do
{
parent = VisualTreeHelper.GetParent(parent as DependencyObject);
} while (parent.GetType() != typeof(Canvas));
Canvas canvas = parent as Canvas;
if (canvas.ActualWidth + e.HorizontalChange < canvas.MinWidth)
{
e.Handled = true;
}
}
catch
{
}
}
This is the only way i find working. Do hope there is a simpler way.
I wanted to apply a minwidth to all columns, so I wrote this:
public static class GridViewConstraints
{
public static readonly DependencyProperty MinColumnWidthProperty =
DependencyProperty.RegisterAttached("MinColumnWidth", typeof(double), typeof(GridViewConstraints), new PropertyMetadata(75d, (s,e) =>
{
if(s is ListView listView)
{
listView.Loaded += (lvs, lve) =>
{
if(listView.View is GridView view)
{
foreach (var column in view.Columns)
{
SetMinWidth(listView, column);
((System.ComponentModel.INotifyPropertyChanged)column).PropertyChanged += (cs, ce) =>
{
if (ce.PropertyName == nameof(GridViewColumn.ActualWidth))
SetMinWidth(listView, column);
};
}
}
};
}
}));
private static void SetMinWidth(ListView listView, GridViewColumn column)
{
double minWidth = (double)listView.GetValue(MinColumnWidthProperty);
if (column.Width < minWidth)
column.Width = minWidth;
}
public static double GetMinColumnWidth(DependencyObject obj) => (double)obj.GetValue(MinColumnWidthProperty);
public static void SetMinColumnWidth(DependencyObject obj, double value) => obj.SetValue(MinColumnWidthProperty, value);
}
Just drop it on your listview:
<ListView b:GridViewConstraints.MinColumnWidth="255" />
Update to the solution of Billy Jake O'Connor who gave the most simple, easy to implement and WORKING CORRECTLY solution of them all.
For the people who don't want all columns to share the same minimum width, with the next code update you can set specific minimum width for each column separately specifying the min width directly in the column properties.
public static class GridColumn {
public static readonly DependencyProperty MinWidthProperty =
DependencyProperty.RegisterAttached("MinWidth", typeof(double), typeof(GridColumn), new PropertyMetadata(75d, (s, e) => {
if(s is GridViewColumn gridColumn ) {
SetMinWidth(gridColumn);
((System.ComponentModel.INotifyPropertyChanged)gridColumn).PropertyChanged += (cs, ce) => {
if(ce.PropertyName == nameof(GridViewColumn.ActualWidth)) {
SetMinWidth(gridColumn);
}
};
}
}));
private static void SetMinWidth(GridViewColumn column) {
double minWidth = (double)column.GetValue(MinWidthProperty);
if(column.Width < minWidth)
column.Width = minWidth;
}
public static double GetMinWidth(DependencyObject obj) => (double)obj.GetValue(MinWidthProperty);
public static void SetMinWidth(DependencyObject obj, double value) => obj.SetValue(MinWidthProperty, value);
}
And the XAML could be something like this ("local" is your using namespace name, modify accordingly)
<ListView>
<ListView.View>
<GridView>
<GridViewColumn local:GridColumn.MinWidth="25" />
<GridViewColumn local:GridColumn.MinWidth="100" />
<GridViewColumn local:GridColumn.MinWidth="200" />
</GridView>
</ListView.View>
</ListView>
You can try this, for each column, if you want to set different minimum width for all columns and maximum to auto
<ListView.View>
<GridView >
<GridViewColumn Header="FILE NAME" DisplayMemberBinding="{Binding fileName}" Width="auto" >
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="MinWidth" Value="200" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
<GridViewColumn Header="ERROR DETAILS" DisplayMemberBinding="{Binding errorMessage}" Width="auto">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="MinWidth" Value="396" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
</GridView>
</ListView.View>

WPF: How to set column width with auto fill in ListView with custom user control

A ListView with Datatemplate in GridViewColumn:
<ListView Name ="LogDataList" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding LogDataCollection}" Background="Cyan">
<ListView.View>
<GridView AllowsColumnReorder="true"
ColumnHeaderToolTip="Event Log Information">
<GridViewColumn Header="Event Log Name" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<l:MyTextBlock Height="25" DataContext="{Binding LogName, Converter={StaticResource DataFieldConverter}}" HighlightMatchCase="{Binding Element}" Loaded="EditBox_Loaded"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...
</GridView>
</ListView.View>
</ListView>
I have no idea about how to make column width autofill although I have tried a lot of way to walk up.
The general idea for demo is :
<ListView Name ="LogDataList" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding LogDataCollection}" Background="Cyan">
<ListView.Resources>
<Style x:Key="ColumnWidthStyle" TargetType="{x:Type GridViewColumn}">
<Style.Setters>
<Setter Property="HorizontalContentAlignment" Value="Stretch" >
</Setter>
</Style.Setters>
</Style>
</ListView.Resources>
<ListView.View>
<GridView AllowsColumnReorder="true"
ColumnHeaderToolTip="Event Log Information">
<GridViewColumn Header="Event Log Name" DisplayMemberBinding="{Binding Path=LogName}" HeaderContainerStyle="{StaticResource ColumnWidthStyle}">
It works, but not accord with my demand. I need to customize datatemplate with my custom user control(MyTextBlock) since the enhancement(HighlighMatchCase property) and binding datacontext.
How can I set up ColumnWidthMode with Fill in the word? On-line'in.
I really appreciate your help.
This is work for me. First, add Text property to MyTextBlock since it is not inherited from System.Windows.Controls.TextBlock but User Control.
public object Text
{
get { return GetValue(TextProperty); }
set
{
SetValue(TextProperty, value);
}
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(object),
typeof(MyTextBlock),
new PropertyMetadata(null, new PropertyChangedCallback(TextChangedCallback)));
static void TextChangedCallback(DependencyObject property,
DependencyPropertyChangedEventArgs args)
{
MyTextBlock textBox = (MyTextBlock)property;
textBox.textBlock.Text = args.NewValue.ToString();
}
Then, resize column width manually like this:
private void ResizeColumnWidth()
{
foreach (GridViewColumn column in LogGridView.Columns)
{
column.Width = column.ActualWidth;
column.Width = double.NaN;
}
}

Resources