|
Ah I was under the impression you were parsing the data from the CSV question
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
To "like" SQLite and dislike SQL Server is not logical since from a "client" point point of view they are virtually identical; and with an ORM indistinguishable.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
I like SQLite, but don't like the database creation part of it.
I don't like having SQL server or Express running on my machine.
And I haven't tried the new Linux version of SQL server that can run in a container and I think is open source. That's something I might like.
I was audited by the BSA recently, Microsoft came after me, and we came to an agreement that is fair for all parties. So I just stay away from their server products now. I don't like SQL Server from a business point of view.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Quote: I like SQLite, but don't like the database creation part of it.
using ( SqlCeEngine engine = new SqlCeEngine( "connection string" ) ) {
engine.CreateDatabase();
}
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Your question seems to be whether you should continue to use DI in a Windows application, or whether you should fall back to tightly-coupled classes.
Stick with DI. It will make your code easier to test. You just need to add the boilerplate code for registering the services yourself if the project template doesn't already include it.
Add a reference to Microsoft.Extensions.DependencyInjection , and modify the Main method to build and populate the service provider.
using Microsoft.Extensions.DependencyInjection;
static class Program
{
public static IServiceProvider ServiceProvider { get; private set; }
private static void ConfigureServices(IServiceCollection services)
{
...
}
static void Main()
{
var services = new ServiceCollection();
ConfigureServices(services);
ServiceProvider = services.BuildServiceProvider();
...
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That's what I was trying to achieve.
The example is a little fuzzy, but I'll give it a try, and do some searching on DI for Windows app
Thanks!
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
It works, pretty fast speed.
But it's kind of weird.
Dependency Injection in Win Forms or Desktop Application .NET Core | TheCodeBuzz
I set up the forms, and used my main Form.
And then from the main form, passed it to the menu form, and next to the Amazon form, deep down to dialog forms.
I kind of thought the forms would just pick up respository or service.
private static void ConfigureServices(IServiceCollection services)
{
services.AddScoped<MainForm>();
services.AddScoped<MenuForm>();
services.AddScoped<AmazonForm>();
services.AddScoped<AmazonDownloadForm>();
services.AddScoped<AmazonOrderDialogForm>();
services.AddScoped<AmazonViewOrdersForm>();
services.AddScoped<DownloadFileProcessorDialog>();
services.AddScoped<EBayForm>();
services.AddScoped<EBayDownloadForm>();
<pre>
services.AddTransient<IOrdersRepository, OrdersRepository>();
services.AddSingleton<IGmailSender, GmailSender>();
}
Called the main form
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
var mainForm = serviceProvider.GetRequiredService<MainForm>();
mainForm.Shown += Main_Shown;
mainForm.FormClosed += Main_FormClosed;
Application.Run(mainForm);
}
Main form loads the menu form
var menuForm = new MenuForm(_ordersRepository)
{
MdiParent = this,
Dock = DockStyle.Fill
};
menuForm.Show();
Menu Form loads the Amazon Form
private void Btn_Amazon_Click(object sender, EventArgs e)
{
for (var i = Application.OpenForms.Count - 1; i >= 1; i += -1)
{
var form = Application.OpenForms[i];
if (form.Name != "MainForm")
form.Close();
}
var amazonForm = new AmazonForm(_ordersRepository)
{
MdiParent = MainForm.ActiveForm,
Dock = DockStyle.Fill
};
amazonForm.Show();
Application.DoEvents();
}
Well at least I got first working.
I'll play around with the 2nd part, and do lots or reading on the subject.
But the orderRepository works, my test example. I have 10 db respositories and don't want to pass them all up the chain.
I thought is was hard to understand how it works for web projects, this is probably more simple, but I just don't get it yet.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Figured how to open more forms down the line
I was passing parameters to forms
like var dbCredentialsFormDI = new DbCredentialsForm(false);
Now I have ...
var dbCredentialsFormDI = serviceProvider.GetRequiredService<DbCredentialsForm>();
dbCredentialsFormDI.firstTime = false;
dbCredentialsFormDI.Dock = DockStyle.None;
dbCredentialsFormDI.StartPosition = FormStartPosition.CenterScreen;
var result = dbCredentialsFormDI.ShowDialog();
if (result == DialogResult.OK)
{
Application.DoEvents();
}
I changed this form from this
public partial class DbCredentialsForm : Form
{
private readonly bool _firstTime;
public DbCredentialsForm(bool firstTime)
{
InitializeComponent();
_firstTime = firstTime;
OK_Button.Enabled = false;
}
To this, I don't it's right.
public partial class DbCredentialsForm : Form
{
public bool firstTime { get; set; }
public DbCredentialsForm()
{
InitializeComponent();
OK_Button.Enabled = false;
}
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
That's pretty slick!
I converted all my database calls, and upgraded all the forms, in how I call them.
Converted all my repository files.
And built some services.
Got the hang of it now.
This is the way making a Windows app should be.
For me at least, because I've already wrote so many of the services I need with Direct Injection.
Thanks Richard for the point in the right direction.
[edit]
This .Net Core Win App is really cool.
I like it so far. I have no clue how to make an install app for it, and wonder if it really works on MacOS and Linux.
So far so good.
I had to use VS2019 Preview to get the form designer, it's a little bumpy and rough. Doesn't have the rename intellisense.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
With autofac I'm to add a parameter to the constructor and even more, the parameter can be optional
Builder
.RegisterAssemblyTypes(assemblies)
.Where(t => typeof(T).IsAssignableFrom(t))
.SingleInstance()
.AsSelf()
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IMyService),
(pi, ctx) => ctx.ResolveOptional<IMyService>() ));
Could you help do this with the default MS dependency container and Scrutor?
What should I add here:
<pre lang="c#">
Builder
.Scan(s =>
s.FromAssemblies(assemblies)
.AddClasses(c => c.AssignableTo(typeof(T)))
.AsSelf()
.WithTransientLifetime() );
Thank you in advance for help and answer
|
|
|
|
|
If the constructor parameter is optional, it should just work:
public class Foo
{
public IBar Bar { get; }
public IBaz Baz { get; }
public Foo(IBar bar = default, IBaz baz = default) (Bar, Baz) = (bar, baz);
}
...
IServiceCollection services = new ServiceCollection();
services.AddTransient<IBaz, Baz>();
services.AddTransient<Foo>();
IServiceProvider provider = services.BuildServiceProvider();
Foo foo = provider.GetRequiredService<Foo>();
Debug.Assert(foo != null);
Debug.Assert(foo.Baz != null);
Debug.Assert(foo.Bar == null); It doesn't matter whether you register the services manually or use Scrutor.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi. I created a user control which has a textbox and a combobox. Depending on the state of the screen (navigation, creation or editing) one of them is visible and the other is invisible. This user control works with a database. Now what I need is to create a method for this component which should work the same way as the SelectedItemChanged of the combobox.
Can anyone help me?
Thanks.
|
|
|
|
|
It would help to know what UI you are using.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Hi, Mycroft (nice name).
Please see the answer to Ralf, in this same post.
Thank you.
|
|
|
|
|
It would also help if you describe what EXACTLY should happen.
I suppose you are using FORMS.
Perhaps ... basicly you should take a look to the functionality of Events ... that could be a way for you ...
|
|
|
|
|
Hi Ralf and thanks for your interest.
I’m using C# in Visual Studio and this application is in forms. The component I’ve created is composed of a TextBox and a ComboBox.
For example, suppose the main table is Sales and the secondary tables are Client [CodCli(integer, PK), NameCli(string)] and PayForm [CodPay(integer, PK), DescPay(string)].
In the table Sales, suppose the fields are: NumSale (integer, PK), CodCli (FK for Client), CodPay (FK for PayForm), Price and Date.
Suppose there’s a Grid that shows data from the main table and data related to the other tables. See figure below.
(Sorry, but I coudn't post an image. I'm trying and if I can, you'll see it).
So, when in navigating mode, this is what we see. When you click a register in the grid, the fields below are updated to show the corresponding data.
When you click the Create button (+), both fields Cliente and Forma de Recebimento become Comboboxes so you can choose the client and the pay form. Data are retrieved from the corresponding tables (datasource). The other fields become empty. When you click the edit button (pencil), those fields also become comboboxes, but all fields show the data of the grid.
The component I’ve made is working fine for all of this. My problem is: in create or edit mode, when I select the client, it’s necessary to select the pay forms allowed for that client (cash, credit card or others), which are in another relation table, so to fill the second combobox. If it were a simple combobox, it would be easy: use the SelectedIndexChanged event. But, as the combobox is now part of a User control, I don’t know how to do this. If you need any more information, let me know.
Can you help me?
|
|
|
|
|
Hi ...
you wrote a very complete description ... but (sorry) I didn't understood the problem you have. Perhaps the reason is because I can't see what you are doing ...
A question : where is the real problem when you try to include it to the UserControl ? At the beginning I thought that you don't have any experience with Events - my mistake. I suppose that you also don't have a problem to include a method to the UserControl. I suppose that you problem is to access the data which is "outside" the UserControl (perhaps part of the Form) ? Please write something more - not only for me ...
|
|
|
|
|
Hi, Ralf. And thank you again for trying to help me.
My component is already accessing the external data, without problem. The fact is that I don’t know how to create the event. In fact I know how to create an event, but I don't know how to associate it to the click of the user in selecting a client: I need to create an event in the User Control that triggers when the user selects a client in the combobox. I suppose it would be similar to the SelectedIndexChange that exists in the combobox. Could you help me to do this? If you need any information, please let me know.
And thanks again.
modified 5-Sep-20 19:00pm.
|
|
|
|
|
Hi again,
in fact it is a problem for me to understand where you stuck.
You know how to work with Events ?
If Yes : the SelectedIndexChanged-Event would be useful for you ?
So : because the Combobox is part of your UserControl the Eventhandler-method from the Combobox must also be part of the UserControl.
Did you realized it like that ?
If Yes : where exactly is your problem ?
You have assigned this method to the Event of the Combobox ?
My problem at this point is that I don't know anything about your knowledge and/or experience. Perhaps my questions are to low in their level ... or at the right point - i don't know. So it's your turn to help me to help you ...
|
|
|
|
|
Hi, Ralf.
I think I coudn't explain exactly my doubts. But in another forum I found the answer to my questions and I was able to finish my component.
If you are interested, the article is:
c# - Call SelectedIndexChanged on ComboBox within User Control - Stack Overflow[^]
There I could see how I can make the Combobox SelectedIndexChanged event available to the user control.
And once again, thanks for your efforts to help me.
|
|
|
|
|
OK ... if it is realized ...
But exactly that was the thing I supposed ...
We could get there here ... if you answered my last questions ...
|
|
|
|
|
Right,Ralf.
Yes. I think you are right.
You had helped me some times. I appreciate that.
I wish you luck.
|
|
|
|
|
Suppose in my project I'm referencing another project as follows:
using static ProjectA;
Prior to using the static keyword in the using statement, one of my methods was able to create an instance object of a class called Products from ProjectA, set the values of its members, and return the instance object of this class as shown below:
Product prod = new Models.Product();
prod.ID = unit.ID;
prod.Dept =unit.Department;
return prod;
Now I'm getting errors stating that I cannot use an instance object to access members of the Product class. I tried to resolve this issue by going to the Product class in ProjectA, adding the static keyword to the ID and Dept properties, and creating a static constructor. I can now set values of the ID and Dept properties using the class name as shown below:
Product.ID = unit.ID;
Product.Dept =unit.Department;
The only problem I have now is I'm still getting an error stating that I cannot use an instance object to access members of the Product class on the line Product prod = new Models.Product();. Please point out what I'm doing wrong.
|
|
|
|
|
using static takes a fully-qualified type name, and makes the static members and nested types of that type available without prefixing them with the class name.
For example:
using static System.Console;
...
WriteLine("Foo"); using static directive - C# Reference | Microsoft Docs[^]
Based on your description, ProjectA is a namespace; in which case, you just need using , not using static .
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
modified 4-Sep-20 9:09am.
|
|
|
|
|
Richard Deeming wrote: of that type available with prefixing them I think you meant "without".
|
|
|
|