Created
September 13, 2018 01:28
-
-
Save veigr/e399cec9da96bfaf64bbefad11c7e268 to your computer and use it in GitHub Desktop.
ListView の列幅を自動的に調整する Behavior
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Specialized; | |
using System.ComponentModel; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Interactivity; | |
namespace BehaviorSample.Views.Behaviors | |
{ | |
/// <summary> | |
/// ListViewの列幅を自動的に調整する | |
/// </summary> | |
public class AutoAdjustColumnWidthBehavior : Behavior<ListView> | |
{ | |
#region DependencyProperties | |
#region IsAdjustOnTargetUpdated | |
/// <summary> | |
/// TargetUpdated時に列幅を自動調整する。 | |
/// BindingでNotifyOnTargetUpdatedをtrueにする必要がある。 | |
/// </summary> | |
public bool IsAdjustOnTargetUpdated | |
{ | |
get { return (bool)GetValue(IsAdjustOnTargetUpdatedProperty); } | |
set { SetValue(IsAdjustOnTargetUpdatedProperty, value); } | |
} | |
/// <summary> | |
/// TargetUpdated時に列幅を自動調整する。 | |
/// BindingでNotifyOnTargetUpdatedをtrueにする必要がある。 | |
/// </summary> | |
public static readonly DependencyProperty IsAdjustOnTargetUpdatedProperty = | |
DependencyProperty.Register(nameof(IsAdjustOnTargetUpdated), typeof(bool), typeof(AutoAdjustColumnWidthBehavior), new PropertyMetadata(true)); | |
#endregion | |
#region IsAdjustOnMouseLeftButtonUp | |
/// <summary> | |
/// MouseLeftButtonUp時に列幅を自動調整する。 | |
/// </summary> | |
public bool IsAdjustOnMouseLeftButtonUp | |
{ | |
get { return (bool)GetValue(IsAdjustOnMouseLeftButtonUpProperty); } | |
set { SetValue(IsAdjustOnMouseLeftButtonUpProperty, value); } | |
} | |
/// <summary> | |
/// MouseLeftButtonUp時に列幅を自動調整する。 | |
/// </summary> | |
public static readonly DependencyProperty IsAdjustOnMouseLeftButtonUpProperty = | |
DependencyProperty.Register(nameof(IsAdjustOnMouseLeftButtonUp), typeof(bool), typeof(AutoAdjustColumnWidthBehavior), new PropertyMetadata(true)); | |
#endregion | |
#region IsAdjustOnMouseWheel | |
/// <summary> | |
/// MouseWheel時に列幅を自動調整する。 | |
/// </summary> | |
public bool IsAdjustOnMouseWheel | |
{ | |
get { return (bool)GetValue(IsAdjustOnMouseWheelProperty); } | |
set { SetValue(IsAdjustOnMouseWheelProperty, value); } | |
} | |
/// <summary> | |
/// MouseWheel時に列幅を自動調整する。 | |
/// </summary> | |
public static readonly DependencyProperty IsAdjustOnMouseWheelProperty = | |
DependencyProperty.Register(nameof(IsAdjustOnMouseWheel), typeof(bool), typeof(AutoAdjustColumnWidthBehavior), new PropertyMetadata(true)); | |
#endregion | |
#region IsAdjustOnKeyUp | |
/// <summary> | |
/// KeyUp時に列幅を自動調整する。 | |
/// </summary> | |
public bool IsAdjustOnKeyUp | |
{ | |
get { return (bool)GetValue(IsAdjustOnKeyUpProperty); } | |
set { SetValue(IsAdjustOnKeyUpProperty, value); } | |
} | |
/// <summary> | |
/// KeyUp時に列幅を自動調整する。 | |
/// </summary> | |
public static readonly DependencyProperty IsAdjustOnKeyUpProperty = | |
DependencyProperty.Register(nameof(IsAdjustOnKeyUp), typeof(bool), typeof(AutoAdjustColumnWidthBehavior), new PropertyMetadata(true)); | |
#endregion | |
#region IsAdjustOnTouchUp | |
/// <summary> | |
/// TouchUp時に列幅を自動調整する。 | |
/// </summary> | |
public bool IsAdjustOnTouchUp | |
{ | |
get { return (bool)GetValue(IsAdjustOnTouchUpProperty); } | |
set { SetValue(IsAdjustOnTouchUpProperty, value); } | |
} | |
/// <summary> | |
/// TouchUp時に列幅を自動調整する。 | |
/// </summary> | |
public static readonly DependencyProperty IsAdjustOnTouchUpProperty = | |
DependencyProperty.Register(nameof(IsAdjustOnTouchUp), typeof(bool), typeof(AutoAdjustColumnWidthBehavior), new PropertyMetadata(true)); | |
#endregion | |
#endregion | |
/// <summary> | |
/// 列幅リサイズRoutedEventハンドラ | |
/// </summary> | |
private readonly RoutedEventHandler ResizeColumnsEventHandler; | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
public AutoAdjustColumnWidthBehavior() | |
{ | |
this.ResizeColumnsEventHandler = new RoutedEventHandler(this.ResizeColumns_OnRoutedEvent); | |
} | |
protected override void OnAttached() | |
{ | |
base.OnAttached(); | |
this.AssociatedObject.TargetUpdated += AddItemsSourceUpdatedHandler; | |
this.AssociatedObject.TargetUpdated += ResizeColumns_OnTargetUpdated; | |
this.AssociatedObject.AddHandler(UIElement.MouseLeftButtonUpEvent, ResizeColumnsEventHandler, true); | |
this.AssociatedObject.AddHandler(UIElement.MouseWheelEvent, ResizeColumnsEventHandler, true); | |
this.AssociatedObject.AddHandler(UIElement.KeyUpEvent, ResizeColumnsEventHandler, true); | |
this.AssociatedObject.AddHandler(UIElement.TouchUpEvent, ResizeColumnsEventHandler, true); | |
} | |
protected override void OnDetaching() | |
{ | |
base.OnDetaching(); | |
this.AssociatedObject.TargetUpdated -= AddItemsSourceUpdatedHandler; | |
this.AssociatedObject.TargetUpdated -= ResizeColumns_OnTargetUpdated; | |
this.AssociatedObject.RemoveHandler(UIElement.MouseLeftButtonUpEvent, ResizeColumnsEventHandler); | |
this.AssociatedObject.RemoveHandler(UIElement.MouseWheelEvent, ResizeColumnsEventHandler); | |
this.AssociatedObject.RemoveHandler(UIElement.KeyUpEvent, ResizeColumnsEventHandler); | |
this.AssociatedObject.RemoveHandler(UIElement.TouchUpEvent, ResizeColumnsEventHandler); | |
} | |
#region ResizeHandlers | |
/// <summary> | |
/// ItemsSource更新時に各列幅をリサイズする | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
private void AddItemsSourceUpdatedHandler(object sender, EventArgs e) | |
{ | |
var src = this.AssociatedObject.ItemsSource; | |
if (src is INotifyPropertyChanged pSrc) | |
{ | |
WeakEventManager<INotifyPropertyChanged, PropertyChangedEventArgs>.AddHandler( | |
pSrc, | |
"PropertyChanged", | |
ResizeColumns_OnTargetUpdated); | |
} | |
if (src is INotifyCollectionChanged cSrc) | |
{ | |
WeakEventManager<INotifyCollectionChanged, NotifyCollectionChangedEventArgs>.AddHandler( | |
cSrc, | |
"CollectionChanged", | |
ResizeColumns_OnTargetUpdated); | |
} | |
} | |
/// <summary> | |
/// TargetedUpdate時に各列幅をリサイズする | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
private void ResizeColumns_OnTargetUpdated(object sender, EventArgs e) | |
{ | |
if (IsAdjustOnTargetUpdated) | |
ResizeColumns(); | |
} | |
/// <summary> | |
/// 指定のRoutedEvent時に各列幅をリサイズする | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
private void ResizeColumns_OnRoutedEvent(object sender, RoutedEventArgs e) | |
{ | |
if (e.RoutedEvent == UIElement.MouseLeftButtonUpEvent && !IsAdjustOnMouseLeftButtonUp) | |
return; | |
if (e.RoutedEvent == UIElement.MouseWheelEvent && !IsAdjustOnMouseWheel) | |
return; | |
if (e.RoutedEvent == UIElement.KeyUpEvent && !IsAdjustOnKeyUp) | |
return; | |
if (e.RoutedEvent == UIElement.TouchUpEvent && !IsAdjustOnTouchUp) | |
return; | |
ResizeColumns(); | |
} | |
/// <summary> | |
/// 各列幅をリサイズする | |
/// </summary> | |
private void ResizeColumns() | |
{ | |
if (!(this.AssociatedObject is ListView lv)) | |
return; | |
if (!(lv.View is GridView gv)) | |
return; | |
foreach (var c in gv.Columns) | |
{ | |
c.Width = 0; //新たにNaNが設定された場合のみ調整されるため一旦0を入れる | |
c.Width = double.NaN; | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment