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/

Bind DataContext to ViewModel in WPF

<Window x:Class="desktop.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        xmlns:local="clr-namespace:desktop.viewmodel"
        Title="Monitoring" Height="350" Width="525" Loaded="MainWindow_OnLoaded" WindowState="Maximized">
    <Window.DataContext>
        <local:MainWindowViewModel x:Key="ViewModel" />
    </Window.DataContext>
    <DockPanel>
        <telerik:RadMenu Name="MenuMain" VerticalAlignment="Top" DockPanel.Dock="Top">
            <telerik:RadMenuItem Header="Item 1">
                <telerik:RadMenuItem Header="SubItem 1" />
                <telerik:RadMenuItem Header="SubItem 2" />
            </telerik:RadMenuItem>
            <telerik:RadMenuItem Header="Item 2" />
        </telerik:RadMenu>
        <telerik:RadBusyIndicator IsBusy="{Binding  Path=IsBusyIndicatorBusy}">
            <Frame Name="FrameMain" NavigationUIVisibility="Hidden" />
        </telerik:RadBusyIndicator>

    </DockPanel>
</Window>
public partial class MainWindow : Window
    {
        public MainWindowViewModel ViewModel { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            ViewModel = (MainWindowViewModel) DataContext;
        }
     }

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
    {
        if(!EqualityComparer<T>.Default.Equals(field, newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            return true;
        }
        return false;
    }
}

ViewModel

using System.ComponentModel;
using System.Runtime.CompilerServices;
using desktop.Annotations;
using Telerik.Windows.Controls;

namespace desktop.viewmodel
{
    public class MainWindowViewModel : ViewModelBase
    {

        private bool _isBusyIndicatorBusy = false;

        public bool IsBusyIndicatorBusy
        {
            get => _isBusyIndicatorBusy;
            set
            {
                _isBusyIndicatorBusy = value;
                SetProperty(ref _isBusyIndicatorBusy , value);
            }
        }
    }
}

References
https://stackoverflow.com/questions/25267070/setting-datacontext-of-elements-inside-xaml
https://intellitect.com/blog/getting-started-model-view-viewmodel-mvvm-pattern-using-windows-presentation-framework-wpf/

Bind DataContext to Current Window in WPF

XAML way

DataContext="{Binding RelativeSource={RelativeSource Self}}"
DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=UserControl}}">
<UserControl ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
</UserControl>

C# way

using System;
using System.Windows;

namespace WpfTutorialSamples.DataBinding
{
    public partial class DataContextSample : Window
    {
        public DataContextSample()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    }
}

References
https://stackoverflow.com/questions/12430615/datacontext-and-binding-self-as-relativesource
https://wpf-tutorial.com/data-binding/using-the-datacontext/
https://stackoverflow.com/questions/11995318/how-do-i-bind-to-relativesource-self
https://stackoverflow.com/questions/20420001/how-to-set-datacontext-to-self

WPF Start-up

StartupUri Property

<Application x:Class="StartupShutdownDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
          
    </Application.Resources>
</Application>

OnStartup

protected override async void OnStartup(StartupEventArgs e)
{
await Init();
}

References
http://www.blackwasp.co.uk/WPFStartupShutdown.aspx

Pass values (parameters) between XAML pages

1 – Using the query string
Navigating page:

page.NavigationService.Navigate(new Uri("/Views/Page.xaml?parameter=test", UriKind.Relative));

Destination page:

string parameter = string.Empty;
if (NavigationContext.QueryString.TryGetValue("parameter", out parameter)) {
    this.label.Text = parameter;
}

2 – Using NavigationEventArgs
Navigating page:

page.NavigationService.Navigate(new Uri("/Views/Page.xaml?parameter=test", UriKind.Relative));

// and ..

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    // NavigationEventArgs returns destination page
    Page destinationPage = e.Content as Page;
    if (destinationPage != null) {

        // Change property of destination page
        destinationPage.PublicProperty = "String or object..";
    }
}

Destination page:

// Just use the value of "PublicProperty"..

3 – Using Manual navigation
Navigating page:

page.NavigationService.Navigate(new Page("passing a string to the constructor"));

Destination page:

public Page(string value) {
    // Use the value in the constructor...
}

References
https://stackoverflow.com/questions/12444816/how-to-pass-values-parameters-between-xaml-pages

Working with WPF Frame using C# and XAML

<Window x:Class="FrameSample.Window1"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    Title="Window1" Height="300" Width="300">  
    <Grid>          
        <TextBlock>Outside area of frame</TextBlock>  
        <Frame Source="Page1.xaml">              
        </Frame>  
    </Grid>  
</Window>

navigate to a URI in a WPF Frame

<Window x:Class="FrameSample.Window1"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    Title="Window1" Height="300" Width="300">  
    <Grid>  
        <TextBlock>Outside area of frame</TextBlock>  
        <Frame Name="FrameWithinGrid" >  
        </Frame>  
        <Button Height="23" Margin="114,12,25,0"   
                Name="button1" VerticalAlignment="Top" Click="button1_Click">Navigate to C# Corner  
        </Button>  
    </Grid>  
</Window>
private void button1_Click(object sender, RoutedEventArgs e)  
{  
    FrameWithinGrid.Navigate(new System.Uri("Page1.xaml",  
             UriKind.RelativeOrAbsolute));  
}

navigate to an external website URL and opens the ASPX page within a Frame

FrameWithinGrid.Source = new Uri("http://www.c-sharpcorner.com/Default.aspx", UriKind.Absolute);

this code first creates a NavigationWindow and then sets its Source to a URI

NavigationWindow window = new NavigationWindow();  
Uri source = new Uri("http://www.c-sharpcorner.com/Default.aspx", UriKind.Absolute);  
window.Source = source; window.Show();
private void NavigationViewItemHome_OnClick(object sender, RoutedEventArgs e)
{
    FrameMain.Navigate(new PageItems());
}

References
https://www.c-sharpcorner.com/UploadFile/mahesh/using-xaml-frame-in-wpf857/
https://www.youtube.com/watch?v=YoZcAx_0rNM