2013-10-04 2 views
0

Я ищу лучший способ управления объектом моей Windows Form, из другого класса. Pls не отвечает, если ваш ответ «Это не так, как вы делаете это на языках ООП!». Pls заботится о том, что мне нужно:Предоставление контроля других классов объекта формы Windows

У меня есть невидимая панель прогресса в моей Windows-форме. Если я нажму кнопку на моей Windows-форме, файл должен быть загружен, а индикатор выполнения должен выполнить некоторые шаги ... Поскольку операция загрузки файла довольно сложна, я загружаю ее из собственного класса, который предназначен для файлов определенного тип. как:

void TestButton_Click(object sender, EventArgs e) 
{ 
MapFiles.ProcessFile() 
} 

Теперь в методе ProcessFile я хочу, чтобы взять под свой контроль на ProgressBar в моей форме. Это работает, если я делаю ProgessBar общедоступным и статическим. Но у этого есть некоторые недовольства. Вы больше не можете управлять элементом в конструкторе форм.

Было бы легко, если бы я мог просто получить доступ к инстансу объекта моей формы. Но я не знаю, как так как форма инициализируется:

Application.Run(new Form1()); 

Я не хочу делать что-то с наследованием здесь, потому что MapFiles на самом деле не имеют ничего общего с Form1 ...

Есть ли другой/лучший способ взять контроль над этим ProgressBar из другого класса?

+0

Создайте событие на рабочем классе, которое Form1 может подписаться и использовать для получения обновлений индикатора выполнения. – JeremiahDotNet

+0

Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

+0

«Это не так, как вы делаете это на современных языках», и есть причина для этого. Это нарушает инкапсуляцию. Ваш класс, который загружает файл, не должен знать, что ваша форма используется для управления индикатором выполнения. Если вы решите изменить свою форму для использования другого элемента управления, тогда код загрузки файла не должен изменяться. Используйте технику, которая отделяет концепцию прогресса от загрузки файла от концепции того, как вы обнаруживаете этот прогресс. –

ответ

1

Почему вы не просто передать ссылку на прогресс-бар в ваш ProcessFile метод:

MapFiles.ProcessFile(progressBar1); 

Тогда вы можете получить к нему доступ из вашего класса, например:

ProcessFile(ProgressBar progressBar1) 
{ 
    progressBar1.Value = 0; 
} 

ПРИМЕЧАНИЕ: Как вы сказали, это, вероятно, не самый лучший способ. Но вы четко сформулировали свои конкретные требования, поэтому я предлагаю вам дать контроль над классом прогресса.

+0

ты меня заинтересовал. Что было бы лучшим решением? ;) – Vinzenz

+0

@ user2334932: Возможно, было предложено какое-то событие, например ByteBlast. Таким образом, вы не привязываете какие-либо элементы пользовательского интерфейса к вашему классу, что делает его более многоразовым. – musefan

+0

Хорошо, я по-прежнему предпочитаю ваш ответ. Но это не так. Я узнал некоторое время назад, что то, что вы сделали с «ProcessFile (ProgressBar progressBar1)», создает новую локальную переменную, называемую «progressBar1». Это даже не влияет на progressBar в моей форме ... – Vinzenz

0

Если вы не хотите проходить мимо ссылок на свою форму, вы можете сделать что-то вроде этого.

public static class FormSharer 
{ 
    public static YourFormClass Form {get; set;} 
} 

в вашем случае загрузки формы вы

FormSharer.Form = this; 

и от любого другого класса вы просто ссылаться FormSharer.Form

Это, как говорится, это не очень хорошая идея, чтобы сделать это. Но снова вам это нужно, вот и все.

+0

Нет, он не нужен. Это плохая идея по какой-то причине, и есть много подходящих способов решения проблемы. – Servy

0

, пока ваш класс в том же проекте вы можете сделать это:

public class Class1 
{ 
    public void AccessForm() 
    { 
     var thatForm = (Form1)Form.ActiveForm; 

     var progressBar = thatForm.Controls.Cast<Control>().Where(a => a.Name =="progressBar1").FirstOrDefault(); 
     MessageBox.Show(progressBar.Name); 

    } 

} 

Я обновил свой ответ, так что вы не должны делать какие-либо контроля общественного

+0

Даже если переменная, представляющая элемент управления, не является общедоступной, она по-прежнему обращается к элементу управления вне определения формы, а * тот, который является плохим дизайном, независимо от того, используете ли вы именованную переменную или нет. – Servy

+0

он специально попросил не критиковать его подход и мой ответ, как вы получаете доступ к экземплярам экземпляра формы «Предоставление другим классам контроля объекта Windows Form» для его случая, даже не меняя подписи MapFiles.ProcessFile() – vlscanner

+0

1) Это не означает, что вы не можете предложить * правильный * подход в любом случае. Он не сказал, что он * требует * неправильного подхода. 2) Ты был тем, кто сказал, что это предпочтительнее, чтобы сделать контроль публичным. Это действительно не так, это так же плохо. По крайней мере, признать, что это ужасная практика, а не впечатление, что это не так. 3) Требовалось, чтобы подпись «ProcessFile» не была изменена. – Servy

0

Вы можете использовать Progress класс чтобы справиться с этим очень эффективно.

Просто начните определение объекта Progress в обработчике кликов, в котором указывается, как обновить ход; в этом случае, обновив значение индикатора выполнения.

Затем передайте это Progress пример *as an экземпляр IProgress` * вашему работнику.

Затем рабочий может использовать Report для указания прогресса.

private void button1_Click(object sender, EventArgs e) 
{ 
    Progress<int> progress = new Progress<int>(
     percent => progressbar1.Value = percent); 
    DoStuff(progress); 
} 

private void DoStuff(IProgress<int> progress) 
{ 
    Task.Run(() => 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      progress.Report(i); 
      Thread.Sleep(200); //placeholder for real work 
     } 
    }); 
} 

Лучше всего Progress класса даже захватывает текущий SynchronizationContext и использует при вызове прогресса изменил событие, поэтому событие будет иметь возможность стрелять в потоке пользовательского интерфейса, даже если вы звоните Report из другого потока.

Смежные вопросы