P
P
PitSullivan2015-01-15 13:37:31
User interface
PitSullivan, 2015-01-15 13:37:31

How to organize the interaction of the main program and the GUI?

So, I'll try to explain what I need. There is a Windows Forms project in C#. SDI, a few buttons, combo-box, in general, nothing complicated. Event handlers for each element are placed in the Form.cs file. In addition, there are several more files in the project tree, in particular, Program.cs, .designer.cs, etc., you already know all this. And my question is this: where to put the main logic of the program? Where to declare variables that, for example, will store a list of available (connected) devices? How to determine how many devices are already connected? How to handle events related to connecting / disconnecting devices, etc., because they have nothing to do with the GUI and its event handler. I could, for example, create a function to search for available devices, but where do I put the code to call it? And what, if it has to process events related to the appearance/disappearance of devices during the entire time the program is running? I have absolutely no experience in developing programs with a graphical interface and I really really need your help. All that I managed to find at the moment are simple tutorials, which, however, did not go beyond the placement of buttons on the form and pampering with checkboxes.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
M
Maxim Grekhov, 2015-01-22
@Sterk

I would advise you to learn about dependency injection. With its use, everything becomes much easier.
I will give an example of project organization:
1 Module description of interfaces for work

interface ICore {...}
interface IDeviceManager {...}

this module should not have dependencies,
I think data structures can be declared in it, but they also should not have dependencies on other program modules
2 Core module - it should implement all the logic of working with devices (or something else) as a service
class Core : ICore {...}
class DeviceManager : IDeviceManager{...}

this module in dependencies should have only module 1
it should be standalone - run in threads
3 Gui module - there are options here, but they all have one thing in common - using the "dependency injection" design pattern. Here is a container comparison . I use LightInject it's fast and easy.
The method of launching windows with a container on the example of LightInject.
let's say you have a main window and a window with instruments
public partial class MyMainForm
{
    private LightInject.IServiceContainer _container;
    public MyMainForm(LightInject.IServiceContainer container)
    {
        _container = container;
    }
    public void ShowDeviceWindow()
    {
         var form = _container.Create<MyDeviceForm>();
         form.Show();
    }
}
public partial class MyDeviceForm
{
    private IDeviceManager _deviceManager;
    public MyDeviceForm(IDeviceManager devicemanager)
    {
        _deviceManager = devicemanager;
    }
    public void ButtonClick()
    {
     // Здесь вы делаете все что хотите и работаете с менеджером
    // Например загружаете список приборов в лист
    foreach(var device in _deviceManager.GetDevices())
        listBox.Add(device.ToString());
    }

in order not to create all objects and dependencies for windows by hand, we use a container
if you use WinForms, then most likely this should be written in programm.cs
var container = new LightInject.ServiceContainer();
container.RegisterInstance<IServiceContainer>(container);
container.Register<ICore, Core>(new PerContainerLifetime());
container.Register<IDeviceManager, DeviceManager>(new PerContainerLifetime());
var form = container.Create<MyMainForm>();
//Не помню как выводятся окна в WinForms
//Но логика надеюсь понятна
form.Show();

Thus, any window can request from us any interface it needs to work with the kernel \ logic.
In order not to poke IServiceContainer into each window, I would create an IWindowManager in the implementation of which I would receive a container and display a window something like that manager.ShowWindow<MyDeviceForm>();and slip it to all windows. This makes it easier to control the creation of windows.
For WPF, I would advise you to look at various MVVM frameworks Calibrun.Micro , Catel and so on.
There is even a modular system that looks like an IDE gemini
. I don’t know what caused the choice of WinForms, but there are frameworks for it too, but they seem to use the MVP pattern.
For my needs, I wrote a gemini clonewith his vision of some moments. I hope this helps in separating logic and windows, a few years ago I was also looking for information on how to build windows in general, but there was no one to tell.
PS: I typed the code in a text editor, there may be typos and inaccuracies.

E
Eddy_Em, 2015-01-15
@Eddy_Em

So, read about IPC. If you need to quickly operate with data coming from one client, open the socket; if you need to be able to read a bunch of data asynchronously from different clients with a long lifetime, we start a file queue (such as a POSIX queue); if there is enough kernel lifetime, we use sysV queues. Well, and another wagon and a small cart of all kinds of possibilities.

T
twobomb, 2017-07-06
@BushaevDenis

<?PHP
$arr = 
    array("color"=>array(
        array(
        "id"=> "1",
        "name"=> "Цвет",
        "value"=> "красный",
        "photo"=> "http://google.com/"),
        array(
        "id"=>  "2",
        "name"=> "Цвет",
        "value"=> "зеленый",
        "photo"=> "http://google.com/"
        )
     ),
     "razmer"=>array(
        array(
        "id"=> "1",
        "name"=> "Размер",
        "value"=> "900х2000",
        "photo"=> "http://google.com/"
        ),
         array(
        "id"=> "2",
        "name"=>  "Размер",
        "value"=> "800х2000",
        "photo"=> "http://google.com/"
         ),
         array(
        "id"=> "3",
        "name"=>  "Размер",
        "value"=>  "700х2000",
        "photo"=> "http://google.com/"
         ),
         array(
        "id"=> "4",
        "name"=> "Размер",
        "value"=> "600х2000",
        "photo"=> "http://google.com/"
         )
     )
     );

function getMix($arr,$charr = null,$n = null){
    if(!isset($n))
        $n = 0;
    $tmpArr = array_values($arr);
    if(!isset($charr))
        $charr = array();
    $str = "";
    for($i = 0; $i < count($tmpArr[$n]);$i++){
        $mycharr = $charr;
        array_push($mycharr,$tmpArr[$n][$i]["value"]);
        if($n < count($tmpArr)-1)
            $str .= getMix($arr,$mycharr,$n+1);
        else{
            for($j = 0; $j < count($mycharr);$j++)
                $str .= $mycharr[$j]." ";
            $str .= "<br>";
        }
    }
    return $str;
}
   echo getMix($arr);
?>

red900x2000
red800x2000
red700x2000
red600x2000
green900x2000
green800x2000
green700x2000
green600x2000

M
Maxim Timofeev, 2017-07-06
@webinar

I don't understand what is the problem

foreach($arr as $one){
   foreach($one as $item){
      echo $item['name'] . ': ' . item['value'];
   }
}

and if you need it separately, it's even easier
foreach($arr['color'] as $item){
      echo $item['name'] . ': ' . item['value'];
}
///some code
foreach($arr['someelse'] as $item){
      echo $item['name'] . ': ' . item['value'];
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question