Подтвердить что ты не робот

Как использовать отдельные файлы .cs в С#?

Форум; Я новичок, разрабатываю немного кода. Я хотел бы знать, как лучше использовать отдельные файлы .cs, содержащие другие классы и функции. В качестве примера базовой функции хотелось бы нажать кнопку очистки и очистить все поля формы. Код разбивается на три файла .cs. Main.cs, MainForm.Designer.cs и btClear.cs.

MainForm.Designer.cs содержит автоматически созданный конструктор, включая кнопку "Очистить", и текстовые поля, которые я хотел бы очистить.

Я хотел бы иметь код для очистки текстовых полей, содержащихся в btClear.cs. Я понимаю, что было бы просто просто разместить этот код в MainForm.Designer.cs, однако я бы хотел использовать это как шаблон для использования отдельных файлов .cs в качестве стандартной практики.

Может кто-нибудь дать мне пример того, как это сделать?

4b9b3361

Ответ 1

Как это сделать большинство программистов .net:

  • Оставьте весь свой код внутри MainForm.cs, но объявите новый метод для разделения кода, который выполняет очистку.

Я всегда оставляю в методе обработчика события (один VS генерирует при двойном щелчке кнопки) код, чтобы изменить курсор мыши (в случае, если код, который я вызываю, занимает пару секунд или больше для запуска) и уловить все необработанные исключения и поместить мою логику в отдельный закрытый метод:

partial class MainForm : Form // this is MainForm.cs
{
    // This is the method VS generates when you double-click the button
    private void clearButton_Click(object sender, EventArgs e)
    {
        this.Cursor = Cursors.WaitCursor;
        try
        {
            ClearForm();
        }
        catch(Exception ex)
        {
            // ... have here code to log the exception to a file 
            // and/or showing a message box to the user
        }
        finally
        {
            this.Cursor = Cursors.Default;
        }
    }

    private void ClearForm()
    {
        // clear all your controls here
        myTextBox.Clear();
        myComboBox.SelectedIndex = 0;
        // etc...
    }
}

На мой взгляд, если вы хотите следовать традиционному способу делать вещи в .net, вы должны придерживаться этого первого примера.

Перемещение кода из формы .cs файлов рекомендуется , если код не является частью логики формы, например, код доступа к данным или бизнес-логика. В этом случае я не думаю, что очистка контроля формы квалифицируется как бизнес-логика. Это всего лишь часть кода формы и должна оставаться в MainForm.cs.

Но если вы действительно хотите поместить метод ClearForm в другой файл .cs, вы можете создать новый класс и переместить там метод ClearForm. Вам также нужно будет изменить свойство Modifiers каждого элемента управления на Public, чтобы ваш новый класс мог получить доступ к ним извне MainForm. Что-то вроде этого:

public class FormCleaner // this is FormCleaner.cs
{
    public void ClearForm(MainForm form)
    {
        // clear all your controls here
        form.myTextBox.Clear();
        form.myComboBox.SelectedIndex = 0;
        // etc...
    }
}

Вам нужно будет изменить основной код формы на:

partial class MainForm : Form // this is MainForm.cs
{
    // This is the method VS generates when you double-click the button
    private void clearButton_Click(object sender, EventArgs e)
    {
        this.Cursor = Cursors.WaitCursor;
        try
        {
            FormCleaner cleaner = new FormCleaner();
            cleaner.ClearForm(this);
        }
        catch(Exception ex)
        {
            // ... have here code to log the exception to a file 
            // and/or showing a message box to the user
        }
        finally
        {
            this.Cursor = Cursors.Default;
        }
    }
}

Но обратите внимание, что ваш класс FormCleaner должен знать о вашем классе MainForm, чтобы знать, как очистить каждый из элементов формы, или вам нужно будет создать общий алгоритм, способный для прокрутки коллекции Controls любой формы для их очистки:

public class FormCleaner // this is FormCleaner.cs
{
    // 'generic' form cleaner
    public void ClearForm(Form form)
    {
        foreach(Control control on form.Controls)
        {
            // this will probably not work ok, because also
            // static controls like Labels will have their text removed.
            control.Text = "";
        }
    }
}

И, как говорили другие, MainForm.Designer.cs генерируется машиной, и вы никогда не должны размещать там свой собственный код.

Ответ 2

Вы можете использовать класс partial для вашего класса MainForm, поскольку это уже выполняется в MainForm.cs и MainForm.Designer.cs.

btnClear.cs

public partial class MainForm
{
   private void clearForm(object sender, EventArgs e)
   {
     // ...
   }
}

И зарегистрируйтесь для события в MainForm.cs или MainForm.Designer.cs

this.btnClear.click += clearForm;

Edit:

Если вам нужен общий способ сделать это, вы можете установить для свойства Tag значение вашего значения по умолчанию. И с помощью метода расширения вы можете сделать что-то вроде formGroup.Reset();

using System.Windows.Forms;

public class ControlExtensions
{
  public void Reset(this Control control)
  {
    if (control.Tag != null)
    {
      if (control is TextBoxBase && control.Tag is string)
      {
        control.Text = control.Tag as string;
      }
      else if (control is CheckBox && control.Tag is bool)
      {
        control.Checked = control.Tag as bool;
      }
      // etc
    }

    foreach (Control child in control.Children)
      child.Reset();
  }
}

Ответ 3

Один класс для каждого файла .cs является хорошим правилом.

Я не буду отделять специальные функции страницы от отдельных файлов .cs, если вы не планируете инкапсулировать в класс многократного использования.

Edit:

Поместите четкую функцию в кнопку OnClick. Нет причин отделять это.

.aspx файл:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SimpleWebTest._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="ClearButton" runat=server onclick="ClearButton_Click" Text="Button" />
    </div>
    </form>
</body>
</html>

.cs file

using System;

namespace SimpleWebTest
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e) { }

        protected void ClearButton_Click(object sender, EventArgs e)
        {
            using (ComplexOperationThingy cot = new ComplexOperationThingy())
            {
                cot.DoSomethingComplex();
            }
        }
    }
}

ComplexOperationThingy.cs:

using System;

namespace SimpleWebTest
{
    public class ComplexOperationThingy
    {
        ComplexOperationThingy() { }

        public void DoSomethingComplex()
        {
            //Do your complex operation.
        }
    }
}

Ответ 4

Это довольно просто сделать. В файле btClear.cs просто создайте определение класса, например:

public class MyUtility
{
    public static void ClearContents(IEnumerable<Control> controls)
    {
        //TODO: Code that clears contents of controls passed
    }
}

Затем вы можете вызвать его из того места, где содержится пространство имен, сгенерированное сгенерированным классом, с помощью:

MyUtility.ClearContents(SomeControlCollection);

Надеюсь, я не полностью упустил отметку о ваших намерениях.

Ответ 5

В общем, вы не должны помещать свой код в файл MainForm.designer.cs. Файлы *.designer.cs используются Visual Studio, чтобы подключить всю утомительную сантехнику фактически установленных элементов управления в форме.

Любой код, который вы хотите использовать для взаимодействия с элементами управления в форме, должен находиться в файле MainForm.cs. Поэтому, если вы хотите, чтобы функция очищала элементы управления формы, вы должны поместить туда код.

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

Как сказал Крис, в целом размещение одного класса для каждого файла .cs также является хорошей идеей. Когда вы это сделаете, файл должен иметь имя класса, который он содержит. Поэтому, если у вас есть класс с именем MyButtonHelpers, тогда исходный файл должен иметь имя MyButtonHelpers.cs.

Ответ 6

Я считаю, что лучше не напрямую редактировать файл .Designer.cs, особенно с точки зрения Source Control. Вы можете использовать частичные классы, чтобы содержать соответствующий код; в этом случае вы можете использовать MainForm.Designer.cs в качестве примера того, как выполнять частичные классы (например, частичный класс MainForm {}).

Если вы добавляете обработчики событий через Windows Forms Designer, он должен автоматически помещать их в MainForm.cs, а не MainForm.Designer.cs. Если проект растет до любого значительного размера, я часто считаю полезным создавать несколько файлов с частичным классом, по одному для каждой основной группы функциональных возможностей. Это значительно облегчает поиск определенной функции (и связанных функций).

Ответ 7

Соглашение в С# (и многие другие языки) - это один файл для каждого класса (и обычно один класс для каждого файла). Конечно, есть исключения из этого правила, но разделение одного класса на несколько файлов должно быть редким явлением, а не стандартной практикой.

Вы упомянули в комментарии, что вы предвидите более "сложные операции", чем пример, который вы дали. Какие операции вы планируете? До тех пор, пока вы просто говорите о работе с элементами управления формами, логика принадлежит файлу .cs для формы (в данном случае MainForm.cs, а не MainForm.designer.cs - как говорили другие, никогда не изменяйте файл .designer).

Если ваша форма становится слишком сложной, тогда имеет смысл разбить ее на отдельный настраиваемые элементы управления. Это позволит вам уменьшить ваши исходные файлы, но (так как каждый элемент управления сопоставляется с классом) вы придерживаетесь соглашения об одном классе ↔ 1.