GridView DoubleClick - wpf

I have a GridView where I want to detect a doubleclick event on the items in the list, i do it as follows:
<ListView>
<ListView.View >
<GridView >
<GridViewColumn Header="FileName">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding FileName}" MouseDoubleClick="Configuration_MouseDoubleClick"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding CreationDate}" Header="Date"/>
</GridView>
</ListView.View>
</ListView>
The problem is that I can only detect doubleclicks by attaching it to the control in the template.
How can I attach the MouseDoubleClick event to the whole ListViewItem? Is there any solution for that with PRISM?

You can add the MouseDoubleClick event to ListViewItem in the ItemContainerStyle like this
<ListView ...>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Code behind..
void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
//...
}

If you're doing MVVM, you can bridge the gap between codebehind and your viewmodel the usual way--by using an attached behavior:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
public sealed class HandleDoubleClickBehavior
{
public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
"Command", typeof (ICommand), typeof (HandleDoubleClickBehavior), new PropertyMetadata(default(ICommand), OnComandChanged));
public static void SetCommand(DependencyObject element, ICommand value)
{
element.SetValue(CommandProperty, value);
}
public static ICommand GetCommand(DependencyObject element)
{
return (ICommand) element.GetValue(CommandProperty);
}
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.RegisterAttached(
"CommandParameter", typeof (object), typeof (HandleDoubleClickBehavior), new PropertyMetadata(default(object)));
public static void SetCommandParameter(DependencyObject element, object value)
{
element.SetValue(CommandParameterProperty, value);
}
public static object GetCommandParameter(DependencyObject element)
{
return (object) element.GetValue(CommandParameterProperty);
}
private static void OnComandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var c = d as Control;
if (c == null)
throw new InvalidOperationException($"can only be attached to {nameof(Control)}");
c.MouseDoubleClick -= OnDoubleClick;
if (GetCommand(c) != null)
c.MouseDoubleClick += OnDoubleClick;
}
private static void OnDoubleClick(object sender, MouseButtonEventArgs e)
{
var d = sender as DependencyObject;
if (d == null)
return;
var command = GetCommand(d);
if (command == null)
return;
var parameter = GetCommandParameter(d);
if (!command.CanExecute(parameter))
return;
command.Execute(parameter);
}
}
With that in your toolbox, you can write XAML like this (assuming PersonViewModel contains the string properties Name and Title, and an ICommand property named SayHiCommand that expects a string parameter):
<ListView ItemsSource="{Binding Persons}" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="local:HandleDoubleClickBehavior.Command" Value="{Binding SayHiCommand}" />
<Setter Property="local:HandleDoubleClickBehavior.CommandParameter" Value="{Binding Name}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}" />
</GridView>
</ListView.View>
</ListView>

For those here that are using a framework like Prism where the main usercontrol containing the Listview is a View (not a window) that is bound to a viewmodel.
The answer of dlf is the best with these small tweaks:
{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}},
Path=DataContext.SayHiCommand}
And in the special behavior attached property you change the ICommand cast to a DelegateCommand cast.
Works like a charm,
Thank you very much.

Related

WPF Bind UserControl Property inside of the DataTemplate of a GridViewColumn.CellTemplate

I'm trying to figure out how to bind a property of a custom user control that is placed inside of the cell template of a list view control but it's not working. All of the DisplayMemberBinding fields are working as expected, and I'm getting the correct values, but inside of that custom control, nothing is updating.
WPF LIstView Control
<ListView Margin="10" x:Name="lvHistory">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Database" Width="150" DisplayMemberBinding="{Binding ActiveBackup.Database.Name, Mode=TwoWay}" />
<GridViewColumn Header="Start Time" Width="130" DisplayMemberBinding="{Binding ActiveBackup.StartTime, Mode=TwoWay}" />
<GridViewColumn Header="Time Elapsed" Width="100" DisplayMemberBinding="{Binding ActiveBackup.TimeElapsed, Mode=TwoWay}" />
<GridViewColumn Header="P2" Width="100" DisplayMemberBinding="{Binding Progress, Mode=TwoWay}" />
<GridViewColumn x:Name="progressColumn" Header="Progress" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<local:cProgressBarSmall x:Name="pr1" Value="{Binding Progress, Mode=TwoWay}" Visibility="Visible" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Code-Behind in the cProgressBarSmall control.
public partial class cProgressBarSmall : UserControl
{
public ActiveBackup ActiveBackup { get; set; }
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(decimal), typeof(cProgressBarSmall));
private decimal _value;
public decimal Value
{
get
{
return (decimal) GetValue(ValueProperty);
}
set
{
_value = value;
SetValue(ValueProperty, value);
p1.Value = value.ToDoubleNotNull();
pLabel.Text = value.ToPercent(0);
if (value == 0)
{
p1.Visibility = Visibility.Hidden;
pLabel.Visibility = Visibility.Hidden;
}
else if (value.ToDoubleNotNull() >= p1.Maximum)
{
pLabel.Text = "Finished!";
pLabel.Foreground = new SolidColorBrush(Colors.Black);
}
}
}
}
}
I can't find a way to access the "pr1" because it's in a DataTemplate and therefore not directly accessible from the code-behind. Does binding not work through? The column before it (the "P2" column) is just at test column I put in just to make sure that the value is in fact updating and it is and that displays correctly, however the "progressColumn" always just shows the default value.
Is there anything special to data binding inside of a ListView.View > GridView > GridViewColumn > GridViewColumn.CellTemplate > DataTemplate hierarchy?
First, if you put a breakpoint in your setter you'll find that it's not hit by the binding. That's because the Binding is setting the dependency property, not the C# property. They're different. The C# property with get/set is an optional wrapper around the dependency property.
The correct way to do this is to have little or no code behind (code behind's not evil; you just don't need any for this one), but use a binding in the usercontrol xaml to update the UI. You can hide and show controls, and update label text, with style triggers in the usercontrol XAML. You don't need any code behind for this.
But here's the simplest way to adapt your existing code to something that works.
public decimal Value
{
get { return (decimal)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(decimal), typeof(cProgressBarSmall),
new PropertyMetadata(0m, Value_ChangedCallback));
// Has to be static
private static void Value_ChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((cProgressBarSmall)d).OnValueChanged();
}
private void OnValueChanged()
{
p1.Value = Value.ToDoubleNotNull();
pLabel.Text = Value.ToPercent(0);
if (Value == 0)
{
p1.Visibility = Visibility.Hidden;
pLabel.Visibility = Visibility.Hidden;
}
else if (Value.ToDoubleNotNull() >= p1.Maximum)
{
pLabel.Text = "Finished!";
pLabel.Foreground = new SolidColorBrush(Colors.Black);
}
}

Is there a simple way to have a ListView automatically scroll to the most recently added item without having to write any code in the code behind?

I have a ListView which is bound to an observable collection. As items are added to the observable collection, the listview does not automatically scroll to show the most recently added item. I am trying to adhere to good WPF practices and would like to avoid writing any code in the view's code-behind. Is there a simple way to accomplish this through the XAML or the corresponding Model's code?
<ListView HorizontalAlignment="Center" ItemsSource="{Binding ScenarioSnippets}" Background="{x:Null}"
BorderBrush="{x:Null}" BorderThickness="0" SelectionMode="Single" VerticalAlignment="Top"
HorizontalContentAlignment="Center" IsSynchronizedWithCurrentItem="True">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Focusable" Value="False" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView Selector.IsSelected="True" AllowsColumnReorder="False">
<GridView.Columns>
<GridViewColumn CellTemplate="{StaticResource ScenarioSnippetItemCellTemplate}"
HeaderContainerStyle="{StaticResource GridViewHeaderStyle}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
You could use a Blend behavior:
public class AutoScrollToLastItemBehavior : Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
var collection = AssociatedObject.Items.SourceCollection as INotifyCollectionChanged;
if (collection != null)
collection.CollectionChanged += collection_CollectionChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
var collection = AssociatedObject.Items.SourceCollection as INotifyCollectionChanged;
if (collection != null)
collection.CollectionChanged -= collection_CollectionChanged;
}
private void collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
ScrollToLastItem();
}
}
private void ScrollToLastItem()
{
int count = AssociatedObject.Items.Count;
if (count > 0)
{
var last = AssociatedObject.Items[count - 1];
AssociatedObject.ScrollIntoView(last);
}
}
}
XAML:
<ListView ItemsSource="...">
<i:Interaction.Behaviors>
<local:AutoScrollToLastItemBehavior />
</i:Interaction.Behaviors>
</ListView>
(the Behavior and Interaction classes can be found in System.Windows.Interactivity.dll in the Blend SDK)
You need to create an Attached Behavior which will allow your ListView to honor the MVVM paradigm which is what you are ultimately after.
A solution/example with ListBox (easily modified for a ListView) can be found here.

Column tab order's not changing when dragging columns in ListView

Is it possible to bind a control's TabIndex to the column's order in a GridView? Say, we have a GridView with AllowsColumnReorder set to true, and when we dragging a second column to be last, the tab navigation order would remain column-ordered: 1 -> 3 -> 2, and not the 1-> 2 -> 3 as usually. What i want to do is the tab navigation according to real column layout as on second image.
My code for kxaml:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ListView ItemsSource="2"
Grid.Row="1">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn Header="One">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="1"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Two">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="2"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Three">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="3"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Page>
here is an example with datagrid instead
<DataGrid ItemsSource="2" Grid.Row="1">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="One">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="1" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Two">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="2" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Three">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="3" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
EDIT
here is a solution with listview that works, but i think its not the best...
public class CustomGridViewColumn : GridViewColumn
{
public static readonly DependencyProperty ColumnIndexProperty =
DependencyProperty.Register("ColumnIndex", typeof(int), typeof(CustomGridViewColumn),
new FrameworkPropertyMetadata());
public int ColumnIndex {
get { return (int)GetValue(ColumnIndexProperty); }
set { SetValue(ColumnIndexProperty, value); }
}
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
gridView.Columns.CollectionChanged+= new NotifyCollectionChangedEventHandler(gridView_Columns_CollectionChanged);
}
void gridView_Columns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var index = 0;
foreach(CustomGridViewColumn col in gridView.Columns){
col.ColumnIndex=index++;
}
}
}
<ListView KeyboardNavigation.TabNavigation="Cycle">
<ListView.View>
<GridView x:Name="gridView" AllowsColumnReorder="True">
<local:CustomGridViewColumn Header="One" x:Name="col1">
<local:CustomGridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="1" TabIndex="{Binding Path=ColumnIndex, Mode=OneWay, ElementName=col1}"/>
</DataTemplate>
</local:CustomGridViewColumn.CellTemplate>
</local:CustomGridViewColumn>
<local:CustomGridViewColumn Header="Two" x:Name="col2">
<local:CustomGridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="2" TabIndex="{Binding Path=ColumnIndex, Mode=OneWay, ElementName=col2}"/>
</DataTemplate>
</local:CustomGridViewColumn.CellTemplate>
</local:CustomGridViewColumn>
<local:CustomGridViewColumn Header="Three" x:Name="col3">
<local:CustomGridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="3" TabIndex="{Binding Path=ColumnIndex, Mode=OneWay, ElementName=col3}"/>
</DataTemplate>
</local:CustomGridViewColumn.CellTemplate>
</local:CustomGridViewColumn>
</GridView>
</ListView.View>
<ListViewItem>1</ListViewItem>
<ListViewItem>2</ListViewItem>
<ListViewItem>3</ListViewItem>
</ListView>
hope this helps
If you use a DataGrid instead: The columns have a DisplayIndex property, which holds the current index, even when they are reordered.
Here's a big start. The only thing left to do would be to walk the GridView's ListView's Items and set tab index foreach element in the row (//! iterate ListView rows). Some of the logic may be messed up, as code was rushed..
XAML
<GridView
AllowsColumnReorder="True"
Controls:GridViewExtensions.DoTabIndexing="True">...
C#
/// <summary>Provides members helpful to <see cref="GridView"/>.</summary>
public static class GridViewExtensions
{
#region DoTabIndexing
[Category("Common")]
[AttachedPropertyBrowsableForType(typeof(GridView))]
public static bool GetDoTabIndexing(GridView gridView)
{
return (bool)gridView.GetValue(DoTabIndexingProperty);
}
public static void SetDoTabIndexing(GridView gridView, bool value)
{
gridView.SetValue(DoTabIndexingProperty, value);
}
public static readonly DependencyProperty DoTabIndexingProperty =
DependencyProperty.RegisterAttached(
"DoTabIndexing",
typeof(bool), // type
typeof(GridViewExtensions), // container/holder/control
new PropertyMetadata(default(bool), OnDoTabIndexingChanged)
);
private static void OnDoTabIndexingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var gridView = (GridView)d;
if (gridView.AllowsColumnReorder == false) { return; }
var newValue = (bool)e.NewValue;
_indexWatch = new ColumnIndexWatch(gridView);
}
static ColumnIndexWatch _indexWatch;
#endregion DoTabIndexing
/// <summary>Watches for changes in a <see cref="GridView"/>'s columns.</summary>
class ColumnIndexWatch
{
readonly GridView _gridView;
public ColumnIndexWatch(GridView gridView)
{
_gridView = gridView;
gridView.Columns.CollectionChanged += OnItemsPopulated;
}
void OnItemsPopulated(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action != NotifyCollectionChangedAction.Add)
{
_gridView.Columns.CollectionChanged -= OnItemsPopulated;
_gridView.Columns.CollectionChanged += OnItemMoved;
trax = new ColumnIndexCollection(_gridView.Columns);
OnItemMoved(sender, e);
}
}
ColumnIndexCollection trax;
void OnItemMoved(object sender, NotifyCollectionChangedEventArgs e)
{
var movedColumn = e.NewItems[0] as GridViewColumn;
if (movedColumn == null) { return; }
trax.ApplyNewIndex(movedColumn, e.NewStartingIndex);
}
/// <summary>Represents a collection of <see cref="ColumnIndex"/></summary>
class ColumnIndexCollection : Collection<ColumnIndex>
{
public ColumnIndexCollection(IEnumerable<GridViewColumn> columns)
: base(Create(columns)) { }
static IList<ColumnIndex> Create(IEnumerable<GridViewColumn> columns)
{
return columns.Select((t, i) => new ColumnIndex { GridViewColumn = t, Index = i }).ToList();
}
public void ApplyNewIndex(GridViewColumn column, int newIndex)
{
var movedByUser = Items.First(col => col.GridViewColumn == column);
var placeTaken = Items.First(col => col.Index == newIndex);
placeTaken.Index = movedByUser.Index;
movedByUser.Index = newIndex;
movedByUser.Update();
placeTaken.Update();
//! iterate ListView rows
}
}
/// <summary>Represents a <see cref="System.Windows.Controls.GridViewColumn"/> and its index.</summary>
class ColumnIndex
{
public GridViewColumn GridViewColumn { get; set; }
public int Index { get; set; }
public void Update()
{
KeyboardNavigation.SetTabIndex(GridViewColumn, Index);
}
public override string ToString()
{
return string.Format("{0} : {1}", Index, GridViewColumn);
}
}
}
}

Selected item in a listview doesn't unselect

I can select multiple items in a listview. But if i click on one, it turns blue. That's normal, so that shows it is selected. But if i click again on the same item, it doesnt uncheck. So i can't change my selection. Somebody who knows how to fix this stupid little problem?
Edit: This is my listview:
<ListView Height="155" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectedItem="{Binding Path=SelectedQuestionDropList, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True" SelectionMode="Multiple" Margin="0,0,542,436" Background="#CDC5CBC5"
dd:DragDrop.DropHandler="{Binding}" Name="DropListView" ItemsSource="{Binding Path=SelectedExaminationQuestions,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" SelectionChanged="ListView_SelectionChanged_1" VerticalAlignment="Bottom">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Verkorte naam" Width="Auto" DisplayMemberBinding="{Binding Path=ShortName}" />
<GridViewColumn Header="Omschrijving" Width="Auto" DisplayMemberBinding="{Binding Path=Description}" />
<GridViewColumn Header="Type" Width="Auto" DisplayMemberBinding="{Binding Path=Type}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
I was facing a similar problem and found that, while left-click always select the item pointed to, you can use Ctrl + left-click to toggle selection in a list view. This is the default behavior.
You can write a wpf behaviour. Something like:
public class ListViewBehaviour
{
/// <summary>
/// Enfoca automaticament el item sel·leccionat
/// </summary>
public static readonly DependencyProperty AutoUnselectItemProperty =
DependencyProperty.RegisterAttached(
"AutoUnselect",
typeof(bool),
typeof(ListViewBehaviour),
new UIPropertyMetadata(false, OnAutoUnselectItemChanged));
public static bool GetAutoUnselectItem(ListView listBox)
{
return (bool)listBox.GetValue(AutoUnselectItemProperty);
}
public static void SetAutoUnselectItem(ListView listBox, bool value)
{
listBox.SetValue(AutoUnselectItemProperty, value);
}
private static void OnAutoUnselectItemChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
var listView = source as ListView;
if (listView == null)
return;
if (e.NewValue is bool == false)
listView.SelectionChanged -= OnSelectionChanged;
else
listView.SelectionChanged += OnSelectionChanged;
}
private static void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// TODO write custom selection behaviour
}
}
And to apply it to a listview:
<ListView bb:ListViewBehaviour.AutoUnselect="True">
...
</ListView>

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