HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Drag and drop single files on different targets for different purposes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
dragdropdifferentsinglefilesforandtargetspurposes

Problem

I have three text fields (DevExpress ButtonEdits set to read only) on a Windows Forms app. They look like this:

They're used by dragging and dropping a single file on each field.

  • If a dropped file belongs on a particular field (correct file type with legal contents), the file is parsed and its contents are used to populate the corresponding place in the applications object model. The text field changes to reflect the location of the loaded file.



  • If a dropped file does not belong on a particular text field (illegal, incorrect, or corrupt contents), an alert message is shown and the application is unaffected. The text field remains blank/unchanged.



I currently achieve this with the following code:

```
public partial class MainForm : DevExpress.XtraEditors.XtraForm
{

private void MainForm_Load(object sender, EventArgs e)
{
SetDragDropHandlers();
}

// Here the drag drop and drag enter handlers are assigned at most once to each field.
private void SetDragDropHandlers()
{

// REVIEWER: SEE REPETITION 1
/////////////////////////////

// Using -= then += on a handler ensures only one is ever added.

this.TextCalibrationFile.AllowDrop = true;
this.TextCalibrationFile.DragEnter -= new DragEventHandler(ActivateIfSingleFileDrag);
this.TextCalibrationFile.DragEnter += new DragEventHandler(ActivateIfSingleFileDrag);
this.TextCalibrationFile.DragDrop -= new DragEventHandler(TryExtractCalibration);
this.TextCalibrationFile.DragDrop += new DragEventHandler(TryExtractCalibration);

this.TextWhiteBalance.AllowDrop = true;
this.TextWhiteBalance.DragEnter -= new DragEventHandler(ActivateIfSingleFileDrag);
this.TextWhiteBalance.DragEnter += new DragEventHandler(ActivateIfSingleFileDrag);
this.TextWhiteBalance.DragDrop -= new DragEventHandler(TryExtractWhiteBalance);
this.TextWhiteBalance.DragDrop += new DragEventHandler(TryExtractWhiteBal

Solution

You actually don't need to do this:

this.SomeControl.SomeEvent += new SomeEventHandler(SomeDelegate);


You can simply do this:

this.SomeControl.SomeEvent += SomeDelegate;


Armed with this knowledge you can create that method you were craving:

private static void RegisterFileDropHandler(ButtonEdit control, DragEventHandler handler)
{
    control.AllowDrop = true;
    control.DragEnter -= ActivateIfSingleFileDrag;
    control.DragEnter += ActivateIfSingleFileDrag;
    control.DragDrop -= handler;
    control.DragDrop += handler;
}


I'll come back to your other point later if I have time :)

Update

As your second bit of replication:

Create another method:

private static void DoSomethingWithFile(ButtonEdit sender, DragEventArgs evt, string errorMessage)
{
    string[] files = (string[])evt.Data.GetData(DataFormats.FileDrop);
    if (!files.Any())
    {
        return;
    }
    try
    {
        // Figure out which button raised the event - something like:
        // sender.Id
        // Then execute a method specific to that button.
    } 
    catch (ArgumentException ex)
    {
        DisplayAlert(string.Format("{0}\n{1}", errorMessage ,ex.Message);
    }
}


Now all of your handlers just call that method:

private void TryExtractCalibration(object sender, DragEventArgs evt)
{
    DoSomethingWithFile((ButtonEdit)sender, evt, "Could not load Calibration from file!");
}

Code Snippets

this.SomeControl.SomeEvent += new SomeEventHandler(SomeDelegate);
this.SomeControl.SomeEvent += SomeDelegate;
private static void RegisterFileDropHandler(ButtonEdit control, DragEventHandler handler)
{
    control.AllowDrop = true;
    control.DragEnter -= ActivateIfSingleFileDrag;
    control.DragEnter += ActivateIfSingleFileDrag;
    control.DragDrop -= handler;
    control.DragDrop += handler;
}
private static void DoSomethingWithFile(ButtonEdit sender, DragEventArgs evt, string errorMessage)
{
    string[] files = (string[])evt.Data.GetData(DataFormats.FileDrop);
    if (!files.Any())
    {
        return;
    }
    try
    {
        // Figure out which button raised the event - something like:
        // sender.Id
        // Then execute a method specific to that button.
    } 
    catch (ArgumentException ex)
    {
        DisplayAlert(string.Format("{0}\n{1}", errorMessage ,ex.Message);
    }
}
private void TryExtractCalibration(object sender, DragEventArgs evt)
{
    DoSomethingWithFile((ButtonEdit)sender, evt, "Could not load Calibration from file!");
}

Context

StackExchange Code Review Q#100639, answer score: 4

Revisions (0)

No revisions yet.