Skip to content

Instantly share code, notes, and snippets.

@veigr
Created September 13, 2018 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veigr/e399cec9da96bfaf64bbefad11c7e268 to your computer and use it in GitHub Desktop.
Save veigr/e399cec9da96bfaf64bbefad11c7e268 to your computer and use it in GitHub Desktop.
ListView の列幅を自動的に調整する Behavior
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