Micro blog about Answer to the Ultimate Question of Life, the Universe, and Everything
  • Home
    • List all categories
    • Sitemap
  • Downloads
    • WebSphere
    • Hitachi902
    • Hospital
    • Kryptonite
    • OCR
    • APK
  • About me
    • Gallery
      • Italy2022
      • Côte d'Azur 2024
    • Curriculum vitae
      • Resume
      • Lebenslauf
    • Social networks
      • Facebook
      • Twitter
      • LinkedIn
      • Xing
      • GitHub
      • Google Maps
      • Sports tracker
    • Adventures planning
  1. You are here:  
  2. Home
  3. C#

Master - Detail with DataGridView and DataTables example

Details
Written by: Stanko Milosev
Category: C#
Published: 11 October 2024
Last Updated: 19 November 2024
Hits: 552
Here, I gave one example of in-memory DataTables master - detail relationship.

Now I will extend that example with DataGridView.

First lets create master DataTable:

private DataTable CreateMasterDataTable()
{
	DataTable dtMaster = new DataTable("Master");
	dtMaster.Columns.Add("Id", typeof(int));
	dtMaster.Columns.Add("SomeText", typeof(string));
	dtMaster.PrimaryKey =
	[
		dtMaster.Columns["Id"]
	];

	return dtMaster;
}
Now detail DataTable:
private DataTable CreateDetailDataTable()
{
	DataTable dtDetail = new DataTable("Detail");
	dtDetail.Columns.Add("Id", typeof(int));
	dtDetail.Columns.Add("MasterId", typeof(int));
	dtDetail.Columns.Add("SomeText", typeof(string));
	dtDetail.PrimaryKey =
	[
		dtDetail.Columns["Id"]
		, dtDetail.Columns["MasterId"]
	];

	return dtDetail;
}
DataSet:
DataSet dsMasterDetail = new DataSet("MasterDetail");
dsMasterDetail.Tables.Add(CreateMasterDataTable());
dsMasterDetail.Tables.Add(CreateDetailDataTable());
Relation and add relation to DataSet:
DataRelation relMasterDetail = new DataRelation("MasterDetailRelation"
	, dsMasterDetail.Tables["Master"].Columns["Id"]
	, dsMasterDetail.Tables["Detail"].Columns["MasterId"]
);

dsMasterDetail.Relations.Add(relMasterDetail);
Now, lets create BindingSource and attach it to DataSource of DataGridView:
var dsMasterDetail = CreateMasterDetailDataSet();
BindingSource bsMaster = new BindingSource
{
	DataSource = dsMasterDetail,
	DataMember = "Master"
};
dgvMaster.DataSource = bsMaster;

BindingSource bsDetail = new BindingSource
{
	DataSource = bsMaster,
	DataMember = "MasterDetailRelation"
};
dgvDetail.DataSource = bsDetail;
Here notice that DataSource of detail BindingSource I have attached master BindingSource, as DataMember name of relation:
BindingSource bsDetail = new BindingSource
{
	DataSource = bsMaster,
	DataMember = "MasterDetailRelation"
};
Example download from here.

Simple MVVM example in Windows Forms

Details
Written by: Stanko Milosev
Category: C#
Published: 20 May 2024
Last Updated: 20 May 2024
Hits: 863
This is my simplified example of Klaus Loeffelmann article. With my example will just execute MessageBox.Show("Hello world");

First I have started new WinForms with .NET 8.0 support, and installed nuGet package CommunityToolkit.Mvvm, then I have added new button, and the class SimpleCommandViewModel which inherits INotifyPropertyChanged:

public class SimpleCommandViewModel: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    private RelayCommand _sampleCommand;

    public SimpleCommandViewModel()
    {
        _sampleCommand = new RelayCommand(ExecuteSampleCommand);
    }

    public void ExecuteSampleCommand()
        => MessageBox.Show("Hello world");

    public RelayCommand SampleCommand
    {
        get => _sampleCommand;
        set
        {
            if (_sampleCommand == value)
            {
                return;
            }

            _sampleCommand = value;
            OnPropertyChanged();
        }
    }
}
Here notice:
new RelayCommand(ExecuteSampleCommand);
That means that by default my button is enabled, in comparsion of Klaus Loeffelmann article:
new RelayCommand(ExecuteSampleCommand, CanExecuteSampleCommand);
Where his button will enabled only if CanExecuteSampleCommand is set to true.

Now, build it at least once.

Then in Properties -> DataBindings -> Command -> add new Object DataSource -> choose SimpleCommandViewModel, after choose SampleCommand from dropdown list. In Form Load event add code:

private void Form1_Load(object sender, EventArgs e)
{
	simpleCommandViewModelBindingSource.DataSource = new SimpleCommandViewModel();
}
Example download from here.

Post image and additional data to WebAPI

Details
Written by: Stanko Milosev
Category: C#
Published: 14 March 2024
Last Updated: 14 March 2024
Hits: 5087

According to https://stackoverflow.com/a/14413414

Natively WebAPI doesn't support binding of multiple POST parameters. 

Here I already gave two examples of WebAPI with multiple Post parameters. Now I will use similiar approach to send image plus additional data, like file and folder name.

First don't forget in Program.cs to add Service:

builder.Services.AddMvc().AddNewtonsoftJson();

Controller:

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace UploadImageServer.Controllers;

public class UploadImageController : Controller
{
    [HttpPost]
    [Route("UploadImage")]

    public async Task<IActionResult> UploadImage([FromBody] JObject? data)
    {
        if (data is null) return BadRequest(new { message = "No image." });
        string? base64Image = data["image"]?.ToString();

        if (base64Image == null) return BadRequest(new { message = "No image." });
        byte[] imageBytes = Convert.FromBase64String(base64Image);

        Directory.CreateDirectory(data["folderName"]?.ToString() ?? string.Empty);

        string imagePath = $"{data["folderName"]}\\{data["fileName"]}";
        await System.IO.File.WriteAllBytesAsync(imagePath, imageBytes);

        return Ok(new { message = "Image uploaded successfully." });
    }
}
Server download from here.

---

Client:

using Newtonsoft.Json.Linq;
using System.Net.Http.Headers;

string imageUrl = "spring.jpg";
string base64Image = ConvertImageToBase64(imageUrl);
var jsonData = new JObject
{
    ["image"] = base64Image
    , ["fileName"] = "magnolia.jpg"
    , ["folderName"] = "spring"
};
string jsonContent = jsonData.ToString();

using HttpClient client = new HttpClient();
StringContent content = new StringContent(jsonContent);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

HttpResponseMessage response = await client.PostAsync("https://localhost:7028/UploadImage", content);

if (response.IsSuccessStatusCode)
{
    Console.WriteLine("Image uploaded successfully!");
}
else
{
    Console.WriteLine("Failed to upload image. Status code: " + response.StatusCode);
}

static string ConvertImageToBase64(string imagePath)
{
    byte[] imageBytes = File.ReadAllBytes(imagePath);
    return Convert.ToBase64String(imageBytes);
}
Client download from here.

FluentFTP async example

Details
Written by: Stanko Milosev
Category: C#
Published: 24 December 2023
Last Updated: 25 December 2023
Hits: 1448
Here is my example of async version of FluentFTP using log4net with TextBoxAppender which I already described here

For this example I have added following NuGet packages:

FluentFTP

FluentFTP.Logging

log4net

Microsoft.Extensions.Configuration.Json - this package I needed because user name and pass for FTP I have saved in JSON configuration file.

In short code looks like this:

Log4NetLogger log4NetLogger = new Log4NetLogger(log);
AsyncFtpClient client = new AsyncFtpClient(host, user, pass);
client.ValidateCertificate += OnValidateCertificate;
client.Logger = new FtpLogAdapter(log4NetLogger);
await client.AutoConnect();
await client.UploadFile(fileName, "/public_html/kmlTestDelete/test.kml");

private void OnValidateCertificate(BaseFtpClient control, FtpSslValidationEventArgs e)
{
	e.Accept = true;
}
The method OnValidateCertificate I am using to accept any certificate, this part of code I took from here

Class Log4NetLogger looks like this:

using log4net;
using Microsoft.Extensions.Logging;
using ILogger = Microsoft.Extensions.Logging.ILogger;

namespace FluentFTPasyncExample;

public class Log4NetLogger : ILogger
{
    private readonly ILog _log;

    public Log4NetLogger(ILog log)
    {
        _log = log;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        string message = $"{formatter(state, exception)} {exception}";
        if (!string.IsNullOrEmpty(message))
        {
            switch (logLevel)
            {
                case LogLevel.Critical:
                    _log.Fatal(message);
                    break;
                case LogLevel.Debug:
                case LogLevel.Trace:
                    _log.Debug(message);
                    break;
                case LogLevel.Error:
                    _log.Error(message);
                    break;
                case LogLevel.Information:
                    _log.Info(message);
                    break;
                case LogLevel.Warning:
                    _log.Warn(message);
                    break;
                default:
                    _log.Warn($"Encountered unknown log level {logLevel}, writing out as Info.");
                    _log.Info(message, exception);
                    break;
            }
        }
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        switch (logLevel)
        {
            case LogLevel.Critical:
                return _log.IsFatalEnabled;
            case LogLevel.Debug:
            case LogLevel.Trace:
                return _log.IsDebugEnabled;
            case LogLevel.Error:
                return _log.IsErrorEnabled;
            case LogLevel.Information:
                return _log.IsInfoEnabled;
            case LogLevel.Warning:
                return _log.IsWarnEnabled;
            default:
                throw new ArgumentOutOfRangeException(nameof(logLevel));
        }
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return null!;
    }

}
Notice that I am injecting log4net in constructor.

Example download from here.

  1. log4net example
  2. Two examples of WebAPI with multiple Post parameters
  3. HttpClient Get and Post
  4. Automatically restore NuGet packages

Subcategories

WPF

Beginning

Code snippets

NUnit

LINQ

Windows Forms

Page 5 of 39

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10