Allow Incoming Connection from Specific IP Address or Subnet in UFW

Allow Incoming SSH from Specific IP Address or Subnet

sudo ufw allow from 15.15.15.0/24  to any port 22
sudo ufw allow from 15.15.15.65 to any port 22

Allow Incoming Rsync from Specific IP Address or Subnet

sudo ufw allow from 15.15.15.0/24 to any port 873

Allow All Incoming HTTP and HTTPS

sudo ufw allow proto tcp from any to any port 80,443

Allow MySQL from Specific IP Address or Subnet

sudo ufw allow from 15.15.15.0/24 to any port 3306

Allow MySQL to Specific Network Interface

sudo ufw allow in on eth1 to any port 3306

References
https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands

Use await in Class Constructor in C#

use a static async method that returns a class instance created by a private constructor

public class ViewModel       
{       
    public ObservableCollection<TData> Data { get; set; }       

    //static async method that behave like a constructor       
    async public static Task<ViewModel> BuildViewModelAsync()  
    {       
        ObservableCollection<TData> tmpData = await GetDataTask();  
        return new ViewModel(tmpData);
    }       

    // private constructor called by the async method
    private ViewModel(ObservableCollection<TData> Data)
    {
        this.Data = Data;   
    }
}

References
https://stackoverflow.com/questions/8145479/can-constructors-be-async

Value conversion with IValueConverter in WPF

<Window x:Class="WpfTutorialSamples.DataBinding.ConverterSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfTutorialSamples.DataBinding"
        Title="ConverterSample" Height="140" Width="250">
    <Window.Resources>
        <local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBox Name="txtValue" />
        <WrapPanel Margin="0,10">
            <TextBlock Text="Current value is: " />
            <TextBlock Text="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}"></TextBlock>
        </WrapPanel>
        <CheckBox IsChecked="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}" Content="Yes" />
    </StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Data;

namespace WpfTutorialSamples.DataBinding
{
    public partial class ConverterSample : Window
    {
        public ConverterSample()
        {
            InitializeComponent();
        }
    }

    public class YesNoToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            switch(value.ToString().ToLower())
            {
                case "yes":
                case "oui":
                    return true;
                case "no":
                case "non":
                    return false;
            }
            return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if(value is bool)
            {
                if((bool)value == true)
                    return "yes";
                else
                    return "no";
            }
            return "no";
        }
    }
}

References
https://wpf-tutorial.com/data-binding/value-conversion-with-ivalueconverter/

Debug data bindings in WPF using Converter

<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:self="clr-namespace:WpfTutorialSamples.DataBinding"
        Title="DataBindingDebuggingSample" Name="wnd" Height="100" Width="200">
    <Window.Resources>
        <self:DebugDummyConverter x:Key="DebugDummyConverter" />
    </Window.Resources>
    <Grid Margin="10">
        <TextBlock Text="{Binding Title, ElementName=wnd, Converter={StaticResource DebugDummyConverter}}" />
    </Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Data;
using System.Diagnostics;

namespace WpfTutorialSamples.DataBinding
{
    public partial class DataBindingDebuggingSample : Window
    {
        public DataBindingDebuggingSample()
        {
            InitializeComponent();
        }
    }

    public class DebugDummyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Debugger.Break();
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Debugger.Break();
            return value;
        }
    }
}

References
https://wpf-tutorial.com/data-binding/debugging/

Handle and raising events in C#

Events

class Counter
{
    public event EventHandler ThresholdReached;

    protected virtual void OnThresholdReached(EventArgs e)
    {
        EventHandler handler = ThresholdReached;
        handler?.Invoke(this, e);
    }

    // provide remaining implementation for the class
}

Event data

public class ThresholdReachedEventArgs : EventArgs
{
    public int Threshold { get; set; }
    public DateTime TimeReached { get; set; }
}

Event handlers

class Program
{
    static void Main()
    {
        var c = new Counter();
        c.ThresholdReached += c_ThresholdReached;

        // provide remaining implementation for the class
    }

    static void c_ThresholdReached(object sender, EventArgs e)
    {
        Console.WriteLine("The threshold was reached.");
    }
}

References
https://docs.microsoft.com/en-us/dotnet/standard/events/
https://www.tutorialsteacher.com/csharp/csharp-event

Create a bindable property in WPF

public partial class FolderComponent : UserControl
{
    public static readonly DependencyProperty FolderNameProperty = DependencyProperty.Register(
        nameof(FolderName),
        typeof(string),
        typeof(FolderComponent),
        new FrameworkPropertyMetadata(
            "",
            FrameworkPropertyMetadataOptions.AffectsRender,
            new PropertyChangedCallback(OnFolderNameChanged),
            null),
        null);

    public FolderComponent()
    {
        InitializeComponent();
    }

    public string FolderName
    {
        get { return (string) GetValue(FolderNameProperty); }
        set { SetValue(FolderNameProperty, value); }
    }

    private static void OnFolderNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FolderComponent uc = (FolderComponent) d;
        string oldValue = (string) e.OldValue;
        string newValue = (string) e.NewValue;

        uc.TextBlockFolderName.Text = newValue;
    }
}

References
https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/custom-dependency-properties?view=netframeworkdesktop-4.8
https://stackoverflow.com/questions/17629945/how-to-create-a-bindable-property-in-wpf
https://stackoverflow.com/questions/29763254/what-is-the-proper-method-for-creating-a-bindable-property-on-a-user-control-in

ItemsControl in WPF

A simple ItemsControl example

<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="ItemsControlSample" Height="150" Width="200">
    <Grid Margin="10">
        <ItemsControl>
            <system:String>ItemsControl Item #1</system:String>
            <system:String>ItemsControl Item #2</system:String>
            <system:String>ItemsControl Item #3</system:String>
            <system:String>ItemsControl Item #4</system:String>
            <system:String>ItemsControl Item #5</system:String>
        </ItemsControl>
    </Grid>
</Window>

ItemsControl with data binding

<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlDataBindingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ItemsControlDataBindingSample" Height="150" Width="300">
    <Grid Margin="10">
        <ItemsControl Name="icTodoList">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0,0,0,5">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="100" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Title}" />
                        <ProgressBar Grid.Column="1" Minimum="0" Maximum="100" Value="{Binding Completion}" />
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>
using System;
using System.Windows;
using System.Collections.Generic;

namespace WpfTutorialSamples.ItemsControl
{
    public partial class ItemsControlDataBindingSample : Window
    {
        public ItemsControlDataBindingSample()
        {
            InitializeComponent();

            List<TodoItem> items = new List<TodoItem>();
            items.Add(new TodoItem() { Title = "Complete this WPF tutorial", Completion = 45 });
            items.Add(new TodoItem() { Title = "Learn C#", Completion = 80 });
            items.Add(new TodoItem() { Title = "Wash the car", Completion = 0 });

            icTodoList.ItemsSource = items;
        }
    }

    public class TodoItem
    {
        public string Title { get; set; }
        public int Completion { get; set; }
    }
}

The ItemsPanelTemplate property

<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlPanelSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="ItemsControlPanelSample" Height="150" Width="250">
    <Grid Margin="10">
        <ItemsControl>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding}" Margin="0,0,5,5" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <system:String>Item #1</system:String>
            <system:String>Item #2</system:String>
            <system:String>Item #3</system:String>
            <system:String>Item #4</system:String>
            <system:String>Item #5</system:String>
        </ItemsControl>
    </Grid>
</Window>

ItemsControl with scrollbars

<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="ItemsControlSample" Height="150" Width="200">
    <Grid Margin="10">
        <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
            <ItemsControl>
                <system:String>ItemsControl Item #1</system:String>
                <system:String>ItemsControl Item #2</system:String>
                <system:String>ItemsControl Item #3</system:String>
                <system:String>ItemsControl Item #4</system:String>
                <system:String>ItemsControl Item #5</system:String>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

References
https://www.wpf-tutorial.com/list-controls/itemscontrol/