私は最近、作成しているユーザーコントロールにいくつかのドラッグ/ドロップ機能を追加しました。その後のテストなどのためにドラッグ/ドロップの詳細を考慮することが理にかなっていました。コアロジックはDragOnMouseMove<TInput>()
です。これは、ドラッグドロップロジックをコントロールから除外する良い方法ですか?
(フォーマットは簡潔にするためトリミング)
internal class DragState
{
private static readonly Size deadZoneSize = SystemInformation.DragSize;
private Rectangle dragDeadZone = Rectangle.Empty;
private Control owningControl = null;
public BlockTypeDragState(Control owner)
{
// null check boilerplate here
this.owningControl = owner;
return;
}
private bool IsActive
{
get { return this.dragDeadZone != Rectangle.Empty; }
}
public void DragOnMouseMove(
Point mouseAt,
DragDropEffects allowedEffects,
Func<object> generateDragData)
{
this.DragOnMouseMove<object>(
mouseAt,
allowedEffects,
null,
s => generateDragData());
return;
}
public void DragOnMouseMove<TInput>(
Point mouseAt,
DragDropEffects allowedEffects,
TInput generateParm,
Func<TInput, object> generateDragData)
{
// boilerplate null check on generateDragData
if (this.DragShouldStart(mouseAt))
{
object data = generateDragData(generateParm);
this.owningControl.DoDragDrop(data, allowedEffects);
this.Reset();
}
return;
}
public void ListenForDrag(int x, int y)
{
this.dragDeadZone = new Rectangle(new Point(x - (deadZoneSize.Width/2), y - (deadZoneSize.Height/2)), deadZoneSize);
return;
}
public void Reset() { this.dragDeadZone = Rectangle.Empty; }
private bool DragShouldStart(Point mouseClientLocation)
{
if (this.IsActive && !this.dragDeadZone.Contains(mouseClientLocation))
{ return true; }
return false;
}
}
使用法は、その後のようになります。ここにコメントが正である場合、私は(まだそれを一般化していないと私は何かを必要とすることを考えると
private DragState dragState = new DragState(this); // pseudo
// MouseMove event handler
private void HandleMouseMove(object sender, MouseEventArgs e)
{
// Perform the drag/drop.
this.dragState.DragOnMouseMove(
new Point(e.X, e.Y),
DragDropEffects.Copy,
() => this.BuildDataToDragDrop());
return;
}
private void HandleMouseDown(object sender, MouseEventArgs e)
{
if (this.CanDragDrop(sender, e)) this.dragState.ListenForDrag(e.X, e.Y);
}
private void HandleMouseUp(object sender, MouseEventargs e)
{
this.dragState.Reset();
}
2回目のように、私はおそらく)、これは生産コードのために合理的です、または私はComplicatorですか?あなたが保守していたコードでこれを見たなら、あなたは私を厄介な名前と呼ぶでしょうか? :)
すべてのコメントは、名前の提案を含めて大歓迎です。 (DragState
が好きではありません)
例えば、これは良いアイデアだとしたら、parmsで拡張性ポイントを機能させるのがより意味があるかどうかはまだ分かりません(Func<>
そしてOnGenerateData<TInput>(TInput parm)
とOnDropCompleted(DragDropEffects result)
などの必須のオーバーライドを持つ抽象DragStateBase
経由Action<>
それが今であるように)またはOO()