Calling a C# WPF library from C++

 







  1. // ConsoleApplication_Hello.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //

  3. #include <iostream>
  4. #include "Windows.h"
  5. #include <filesystem>
  6. #include <fstream>
  7. #include <string>
  8. #include "combaseapi.h"
  9. #pragma comment(lib,"..\\x64\\Debug\\ClassLibrary1")
  10. #define _hr(X) _ASSERTE(SUCCEEDED(X))
  11. using namespace std;
  12. namespace fs = std::filesystem;
  13. fs::path MyRootPath;
  14. extern "C" __declspec(dllimport)
  15. HRESULT Get_Load_WPF_Library_Interface(void** pMyObj);

  16. struct __declspec(dllimport)  MyCreateInstance {
  17. MyCreateInstance();
  18. HRESULT Create_WPF_Instance(BSTR filename, BSTR CLSID,
  19. IUnknown** pIUnknown);
  20. ~MyCreateInstance();
  21. };

  22. class MyBSTR
  23. {
  24. BSTR _bstr;
  25. public:
  26. MyBSTR(std::wstring str)
  27. {
  28. _bstr = SysAllocStringLen(str.c_str(), str.length());
  29. }
  30. ~MyBSTR() { SysFreeString(_bstr); }
  31. operator BSTR()const { return _bstr; }
  32. };

  33. static void AppInitialize() {
  34. WCHAR ModuleFileName[MAX_PATH];
  35. fs::path ModuleFileName_Path;
  36. if (GetModuleFileNameW(NULL, ModuleFileName, MAX_PATH) > MAX_PATH)
  37. throw exception("GetModuleFileNameW");
  38. wcout << "ModuleFileName=\t" << ModuleFileName << endl;
  39. ModuleFileName_Path = fs::path(ModuleFileName);
  40. MyRootPath = ModuleFileName_Path.
  41. parent_path().parent_path().parent_path().parent_path();
  42. wcout << "MyRootPath=\t" << MyRootPath.wstring() << endl;
  43. }

  44. __interface IMyTest : IDispatch {
  45. HRESULT Hello(INT32 JobID, BSTR MyRootPath);
  46. };
  47. void DoMyJob(MyCreateInstance& MyCreateInstanceObj, int JobID) {
  48. const fs::path WPF_Library_Path =
  49. L"WpfLibrary_Hello\\WpfLibrary_Hello\\bin\\x64\\Debug\\net9.0-windows\\WpfLibrary_Hello.dll";
  50. const std::wstring clsid_in_WPF_Library =
  51. L"{7B3236BC-C3CD-4EC0-85C5-A9EC33C26D7D}";
  52. const std::wstring IID_IMyTest =
  53. L"{0A46DC92-73F3-4B6E-AC34-3F9A1396C163}";
  54. IUnknown* pIUnknown = NULL;
  55. IMyTest* pIMyTest = NULL;
  56. fs::path Library_FullPath = MyRootPath / WPF_Library_Path;
  57. if (!fs::exists(Library_FullPath)) {
  58. wcerr << Library_FullPath.wstring() << endl;
  59. throw exception("File not exist");
  60. }
  61. _hr(MyCreateInstanceObj.Create_WPF_Instance(
  62. MyBSTR(Library_FullPath.wstring()),
  63. MyBSTR(clsid_in_WPF_Library),
  64. &pIUnknown));
  65. IID _IID_IMyTest;
  66. _hr(IIDFromString(IID_IMyTest.c_str(), &_IID_IMyTest));
  67. _hr(pIUnknown->QueryInterface(_IID_IMyTest, (void**)&pIMyTest));
  68. MyBSTR My_RootPath(MyRootPath.wstring().append(L"\\"));
  69. _hr(pIMyTest->Hello(JobID, My_RootPath));
  70. pIUnknown->Release();
  71. cout << "pIMyTest->Release() =" << pIMyTest->Release() << endl;
  72. }
  73. int main()
  74. {
  75. std::cout << "Hello World!\n";
  76. fs::path Current_Directory = fs::current_path();
  77. wcout << "CurrentDir =\t" << Current_Directory.wstring() << endl;
  78. try {
  79. AppInitialize();
  80. _hr(CoInitialize(NULL));
  81. MyCreateInstance MyCreateInstanceObj;
  82. int MyJobID;
  83. cout << "Enter a Job id " << endl
  84. << "1: WpfLibrary_Hello" << endl
  85. << "2: WpfApp_Hello" << endl;
  86. cin >> MyJobID;
  87. if (MyJobID == 1) {
  88. wcout << endl << L" .\\iisexpress " <<
  89. L"/path:" << MyRootPath.c_str() << L"\\WpfWebSite_Hello"
  90. << endl << endl;
  91. system("Pause");
  92. }
  93. DoMyJob(MyCreateInstanceObj, MyJobID);
  94. CoUninitialize();
  95. return 0;
  96. }
  97. catch (exception ex) {
  98. cerr << ex.what() << endl;
  99. return -9;
  100. }
  101. }











  1. #include "pch.h"

  2. #include "Windows.h"
  3. #include <iostream>

  4. #include "ClassLibrary1.h"
  5. using  namespace std;
  6. #define _hr(X) _ASSERTE(SUCCEEDED(X))

  7. // {4BC492CD-E50F-426B-AD24-7C9280A5AF1E}
  8. static const CLSID clsid_Create_WPF_Instance_not_Used =
  9. { 0x4bc492cd, 0xe50f, 0x426b, { 0xad, 0x24, 0x7c, 0x92, 0x80, 0xa5, 0xaf, 0x1e } };

  10. // {2FE5D888-1813-4EA9-A1E1-000650359BFC}
  11. static const IID iid_ICreate_WPF_Instance =
  12. { 0x2fe5d888, 0x1813, 0x4ea9, { 0xa1, 0xe1, 0x0, 0x6, 0x50, 0x35, 0x9b, 0xfc } };

  13. extern "C" __declspec(dllexport)
  14. HRESULT Get_Load_WPF_Library_Interface(void** ppInterface)
  15. {
  16. try {
  17. WpfLibrary_For_Remove_Reference::Class1^ MyWpf_Object =
  18. gcnew WpfLibrary_For_Remove_Reference::Class1();
  19. IUnknown* pIunknown = (IUnknown*)
  20. System::Runtime::InteropServices::Marshal::GetIUnknownForObject(
  21. MyWpf_Object).ToPointer();
  22. pIunknown->QueryInterface(iid_ICreate_WPF_Instance,
  23. ppInterface);
  24. pIunknown->Release();
  25. return S_OK;
  26. }
  27. catch (const System::Exception^ ex) {
  28. return -234;
  29. }
  30. }
  31. __interface ICreate_WPF_Instance : IDispatch {
  32. HRESULT Create_WPF_Instance(BSTR filename, BSTR CLSID,
  33. IUnknown** pIUnknown);
  34. };

  35. static ICreate_WPF_Instance* pICreate_WPF_Instance;

  36. struct __declspec(dllexport) MyCreateInstance {
  37. MyCreateInstance()
  38. {
  39. _hr(Get_Load_WPF_Library_Interface((void**)&pICreate_WPF_Instance));
  40. }
  41. HRESULT Create_WPF_Instance(BSTR filename, BSTR CLSID,
  42. IUnknown** pIUnknown)
  43. {
  44. if (*pIUnknown != NULL)return -44;
  45. return pICreate_WPF_Instance->Create_WPF_Instance(
  46. filename, CLSID, pIUnknown);
  47. }
  48. ~MyCreateInstance() {
  49. ULONG RefCout = pICreate_WPF_Instance->Release();
  50. std::cout << "pICreate_WPF_Instance->Release()=" << RefCout << std::endl;
  51. pICreate_WPF_Instance = NULL;
  52. }
  53. };
  54. #ifdef IMPORT 
  55. struct __declspec(dllimport)  MyCreateInstance {
  56. MyCreateInstance();
  57. HRESULT Create_WPF_Instance(BSTR filename, BSTR CLSID,
  58. IUnknown** pIUnknown);
  59. ~MyCreateInstance();
  60. };
  61. #endif













  1. using System.Runtime.InteropServices;
  2. using System.Windows;

  3. namespace WpfLibrary_For_Remove_Reference
  4. {
  5.     [Guid(Class1.IID_ICreate_WPF_Instance)]
  6.     [ComVisible(true)]
  7.     public interface ICreate_WPF_Instance
  8.     {
  9.         void Create_WPF_Instance(String filename, String CLSID,
  10.             [MarshalAs(UnmanagedType.IUnknown)] ref Object pIUnknown);
  11.     }

  12.     [Guid(clsid_Create_WPF_Instance)]
  13.     [ClassInterface(ClassInterfaceType.None)]
  14.     [ComVisible(true)]
  15.     public class Class1 : ICreate_WPF_Instance
  16.     {
  17.         public const String clsid_Create_WPF_Instance =
  18.             "4BC492CD-E50F-426B-AD24-7C9280A5AF1E";
  19.         public const String IID_ICreate_WPF_Instance =
  20.             "2FE5D888-1813-4EA9-A1E1-000650359BFC";

  21.         void ICreate_WPF_Instance.Create_WPF_Instance(String filename, String CLSID,
  22.             [MarshalAs(UnmanagedType.IUnknown)] ref Object pIUnknown)
  23.         {
  24.             System.Reflection.Assembly Assembly_Library =
  25.                 System.Reflection.Assembly.LoadFrom(filename);
  26.             System.Guid clsid = Guid.Parse(CLSID);
  27.             foreach (System.Type clsid_type in Assembly_Library.GetExportedTypes())
  28.                 if (clsid_type.GUID == clsid)
  29.                     try
  30.                     {
  31.                         System.Object? obj = System.Activator.CreateInstance(clsid_type);
  32.                         if (obj != null) { pIUnknown = obj; return; }
  33.                     }
  34.                     catch (System.Exception exc)
  35.                     {
  36.                         MessageBox.Show(exc.Message);
  37.                         throw;
  38.                     }
  39.             throw new Exception($"My clsid={CLSID}")
  40.             {
  41.                 HResult = -789
  42.             };
  43.         }
  44.     }
  45. }



















  1. using System.Reflection;
  2. using System.Runtime.InteropServices;
  3. using System.Windows;

  4. namespace WpfLibrary_Hello
  5. {
  6.     class MyApp : System.Windows.Application
  7.     {

  8.     }

  9.     [Guid(Class1.IMyTest_IID)]
  10.     [ComVisible(true)]
  11.     public interface IMyTest_WPF
  12.     {
  13.         void Hello(Int32 id, String str);
  14.     }

  15.     [Guid(clsid)]
  16.     [ClassInterface(ClassInterfaceType.None)]
  17.     [ComVisible(true)]
  18.     public partial class Class1 : IMyTest_WPF
  19.     {
  20.         public Class1()
  21.         {
  22.         }
  23.         public const String clsid = "7B3236BC-C3CD-4EC0-85C5-A9EC33C26D7D";
  24.         public const String IMyTest_IID = "0A46DC92-73F3-4B6E-AC34-3F9A1396C163";
  25.         static String My_RootPath = String.Empty;
  26.         static int MyJobID = 0;
  27.         static MyApp? app;
  28.         int hr = 0;
  29.         void IMyTest_WPF.Hello(Int32 id, String myRootPath)
  30.         {
  31.             MyJobID = id;
  32.             My_RootPath = myRootPath;
  33.             try
  34.             {
  35.                 DoWorkInSTA(); return;
  36.                 /*
  37.                 Thread STA_Thread = new Thread(DoWorkInSTA);
  38.                 STA_Thread.SetApartmentState(ApartmentState.STA);
  39.                 STA_Thread.Start();
  40.                 STA_Thread.Join();
  41.                 */
  42.             }
  43.             catch (Exception ex)
  44.             {
  45.                 MessageBox.Show(ex.Message, "Exception meesage");
  46.                 hr = -1;
  47.             }
  48.             if (0 != hr) throw new Exception($"hr={hr}") { HResult = (int)hr };
  49.         }
  50.         [System.STAThreadAttribute()]
  51.         void DoWorkInSTA()
  52.         {
  53.             try
  54.             {
  55.                 app ??= new();
  56.                 Uri MyStartUp_Uri;

  57.                 switch (MyJobID)
  58.                 {
  59.                     case 1:
  60.                         LoadAssembly(
  61. @"WpfLibrary_Hello\WpfLibrary_Hello\bin\x64\Debug\net9.0-windows\Microsoft.Web.WebView2.Wpf.dll"
  62. );

  63.                         MyStartUp_Uri =
  64.                   new Uri(
  65.  @"pack://application:,,,/WpfLibrary_Hello;Component/Page_Home.xaml",
  66.      UriKind.Absolute);
  67.                         //                   @"/WpfLibrary_Hello;Component/Page_Home.xaml",
  68.                         //             UriKind.Relative);
  69.                         break;
  70.                     case 2:
  71.                         {
  72.                             System.Reflection.Assembly[] Ass5 = [
  73.                    LoadAssembly(@"WpfApp_Hello\WpfApp_Hello\bin\x64\Debug\net9.0-windows\WpfApp_Hello.dll") ,
  74.                    LoadAssembly(@"WpfApp_Hello\WpfApp_Hello\bin\x64\Debug\net9.0-windows\WpfControlLibrary_Hello.dll"),
  75.                    LoadAssembly(@"WpfApp_Hello\WpfApp_Hello\bin\x64\Debug\net9.0-windows\WpfCustomControlLibrary_Hello.dll")

  76.                                          ];

  77.                             AddResource(@"/WpfApp_Hello;component/Dictionary1.xaml",
  78.                                                  UriKind.Relative);
  79.                             AddResource(@"/WpfApp_Hello;component/Dictionary2.xaml",
  80.                                                   UriKind.Relative);
  81.                             AddResource(@"pack://application:,,,/WpfCustomControlLibrary_Hello;component/Themes/Generic.xaml",
  82.                                                    UriKind.Absolute);

  83.                             MyStartUp_Uri = new Uri(
  84.                                "/WpfApp_Hello;Component/MainWindow.xaml",
  85.                                UriKind.Relative);
  86.                         }
  87.                         break;
  88.                     default:
  89.                         throw new Exception($"Error : My Job ID is {MyJobID}");
  90.                 }
  91.                 app.StartupUri = MyStartUp_Uri;
  92.                 //MessageBox.Show($"MyJobID = {MyJobID}");
  93.                 app.Run();
  94.                 hr = 0;
  95.             }
  96.             catch (Exception ex)
  97.             {
  98.                 MessageBox.Show($"DoWorkInSTA Exception:\n{ex.Message}");
  99.                 hr = -3;
  100.             }
  101.             static Assembly LoadAssembly(string relativePath) =>
  102.             System.Reflection.Assembly.LoadFrom(My_RootPath +
  103.             relativePath) ?? throw new Exception("LoadFrom error");

  104.             static void AddResource(string Uristr, UriKind Uri_Kind)
  105.             {
  106.                 app?.Resources.MergedDictionaries.Add(
  107.                  new ResourceDictionary()
  108.                  {
  109.                      Source = new Uri(Uristr, Uri_Kind)
  110.                  });
  111.             }

  112.         }
  113.     }
  114. }




  1. <Page x:Class="WpfLibrary_Hello.Page_Home"
  2.       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.       xmlns:local="clr-namespace:WpfLibrary_Hello"
  7.       mc:Ignorable="d" 
  8.       d:DesignHeight="450" d:DesignWidth="800"
  9.       Title="Page_Home">

  10.     <Grid Height="300" VerticalAlignment="Top">
  11.         <Button Content="Use new"   HorizontalAlignment="Left" VerticalAlignment="Top" Click="Click_Use_new"/>
  12.         <Button Content="use Uri "  HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="Click_Use_Uri"/>
  13.         <Button Content="Web View2" HorizontalAlignment="Center" VerticalAlignment="Bottom" Click="Click_WebView"/>
  14.         <TextBlock 
  15.              Width="350" 
  16.              HorizontalAlignment="Center" 
  17.              VerticalAlignment="Center">
  18.             <Hyperlink NavigateUri=
  19.              "https://cheninnjer.blogspot.com/2024/09/marshalling.html" 
  20.              RequestNavigate="Hyperlink_RequestNavigate">
  21.     Click here to go cheninnjer.blogspot.com about marshalling
  22.             </Hyperlink>
  23.         </TextBlock>
  24.     </Grid>
  25. </Page>



  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Navigation;
  15. using System.Windows.Shapes;

  16. namespace WpfLibrary_Hello
  17. {
  18.     /// <summary>
  19.     /// Interaction logic for Page_Home.xaml
  20.     /// </summary>
  21.     public partial class Page_Home : Page
  22.     {
  23.         public Page_Home()
  24.         {
  25.             InitializeComponent();
  26.         }
  27.         private void Click_Use_new(object sender, RoutedEventArgs e)
  28.         {
  29.             NavigationService.Navigate(new Page_WebBrowser());
  30.         }
  31.         private void Click_Use_Uri(object sender, RoutedEventArgs e)
  32.         {
  33.             NavigationService.Navigate(
  34.                 new Uri(
  35.                 "/WpfLibrary_Hello;Component/Page_WebBrowser.xaml",
  36.                 UriKind.Relative)
  37.                 );
  38.         }
  39.         private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
  40.         {
  41.             Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)
  42.             {
  43.                 UseShellExecute = true
  44.             });
  45.             e.Handled = true;
  46.         }

  47.         private void Click_WebView(object sender, RoutedEventArgs e)
  48.         {
  49.             NavigationService.Navigate(
  50.                 new Page_WebView());
  51.         }
  52.     }
  53. }





  1. <Page x:Class="WpfLibrary_Hello.Page_WebBrowser"
  2.       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.       xmlns:local="clr-namespace:WpfLibrary_Hello"
  7.       xmlns:Wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" 
  8.       mc:Ignorable="d" 
  9.       d:DesignHeight="450" d:DesignWidth="800"
  10.       Title="Page_WebBrowser">

  11.     <DockPanel LastChildFill="True">
  12.         <StackPanel  Width="100" DockPanel.Dock="Right">
  13.             <Button Height="50"
  14.                     Content="GoBack or GoForward"
  15.                     Click="Button_Click"/>
  16.             <TextBlock Height="420" x:Name="MyTextBlock"/>
  17.         </StackPanel>
  18.         <WebBrowser DockPanel.Dock="Left"
  19.                     x:Name="webBrowser1" 
  20.                     Source="http://localhost:8080"/>
  21.     </DockPanel>
  22. </Page>



  1. using System.Runtime.InteropServices;
  2. using System.Text;
  3. using System.Windows;
  4. using System.Windows.Controls;
  5. using System.Windows.Media;

  6. namespace WpfLibrary_Hello
  7. {
  8.     /// <summary>
  9.     /// Interaction logic for Page_WebBrowser.xaml
  10.     /// </summary>
  11.     /*
  12.         EXTERN_C const IID IID_IWebBrowserApp;

  13. #if defined(__cplusplus) && !defined(CINTERFACE)

  14.     MIDL_INTERFACE("0002DF05-0000-0000-C000-000000000046")
  15.     IWebBrowserApp : public IWebBrowser
  16.     {
  17.     public:
  18.         virtual HRESULT STDMETHODCALLTYPE Quit(void) = 0;

  19.         virtual HRESULT STDMETHODCALLTYPE ClientToWindow(
  20.              __RPC__inout int* pcx,
  21.              __RPC__inout int* pcy) = 0;

  22.         virtual HRESULT STDMETHODCALLTYPE PutProperty(
  23.              __RPC__in BSTR Property,
  24.              VARIANT vtValue) = 0;

  25.         virtual HRESULT STDMETHODCALLTYPE GetProperty(
  26.              __RPC__in BSTR Property,
  27.              __RPC__out VARIANT *pvtValue) = 0;
  28.         virtual HRESULT STDMETHODCALLTYPE get_Name(
  29.              __RPC__deref_out_opt BSTR *Name) = 0;
  30.         virtual HRESULT STDMETHODCALLTYPE get_HWND(
  31.              __RPC__out SHANDLE_PTR *pHWND) = 0;

  32.         virtual HRESULT STDMETHODCALLTYPE get_FullName(
  33.              __RPC__deref_out_opt BSTR *FullName) = 0;
  34.         virtual HRESULT STDMETHODCALLTYPE get_Path(
  35.              __RPC__deref_out_opt BSTR *Path) = 0;
  36.         virtual HRESULT STDMETHODCALLTYPE get_Visible(
  37.              __RPC__out VARIANT_BOOL *pBool) = 0;
  38.         virtual HRESULT STDMETHODCALLTYPE put_Visible(
  39.              VARIANT_BOOL Value) = 0;

  40.         virtual HRESULT STDMETHODCALLTYPE get_StatusBar(
  41.             __RPC__out VARIANT_BOOL *pBool) = 0;

  42.         virtual HRESULT STDMETHODCALLTYPE put_StatusBar(
  43.              VARIANT_BOOL Value) = 0;

  44.         virtual HRESULT STDMETHODCALLTYPE get_StatusText(
  45.              __RPC__deref_out_opt BSTR *StatusText) = 0;

  46.         virtual HRESULT STDMETHODCALLTYPE put_StatusText(
  47.              __RPC__in BSTR StatusText) = 0;

  48.         virtual HRESULT STDMETHODCALLTYPE get_ToolBar(
  49.              __RPC__out int* Value) = 0;

  50.         virtual HRESULT STDMETHODCALLTYPE put_ToolBar(
  51.              int Value) = 0;

  52.         virtual HRESULT STDMETHODCALLTYPE get_MenuBar(
  53.              __RPC__out VARIANT_BOOL *Value) = 0;

  54.         virtual HRESULT STDMETHODCALLTYPE put_MenuBar(
  55.              VARIANT_BOOL Value) = 0;

  56.         virtual HRESULT STDMETHODCALLTYPE get_FullScreen(
  57.              __RPC__out VARIANT_BOOL *pbFullScreen) = 0;

  58.         virtual HRESULT STDMETHODCALLTYPE put_FullScreen(
  59.             VARIANT_BOOL bFullScreen) = 0;

  60.     };

  61. */

  62.     /*
  63. #if defined(__cplusplus) && !defined(CINTERFACE)

  64.         MIDL_INTERFACE("6d5140c1-7436-11ce-8034-00aa006009fa")
  65.         IServiceProvider : public IUnknown
  66.         {
  67.         public:
  68.             virtual HRESULT STDMETHODCALLTYPE QueryService(
  69.             [annotation][in] _In_ REFGUID guidService,
  70.             [annotation][in]  _In_ REFIID riid,
  71.             [annotation][out] _Outptr_  void** ppvObject) = 0;
  72.         };
  73.     */
  74.     [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  75.     [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
  76.     internal interface IServiceProvider
  77.     {
  78.         [return: MarshalAs(UnmanagedType.IUnknown)]
  79.         object QueryService(ref Guid serviceGuid, ref Guid riid);
  80.     }
  81.     public partial class Page_WebBrowser : Page
  82.     {
  83.         static readonly StringBuilder MyTrace = new();
  84.         static int Count;
  85.         public Page_WebBrowser()
  86.         {

  87.             // MessageBox.Show("1");
  88.             try
  89.             {
  90.                 InitializeComponent();
  91.                 MyInitilize(webBrowser1);
  92.             }
  93.             catch (Exception ex)
  94.             {
  95.                 MessageBox.Show($"{ex.Message}", "InitializeComponent error");
  96.             }
  97.         }
  98.         void MyInitilize(WebBrowser MyWebBrowser)
  99.         {
  100.             try
  101.             {
  102.                 MyTrace.Clear();
  103.                 MyTrace.AppendLine("Page_WebBrowser 1");
  104.                 var IserviceProvider =
  105.              (IServiceProvider)MyWebBrowser.Document
  106.              ?? throw new Exception("IserviceProvider == null");
  107.                 Guid IID_IWebBrowserApp = new("0002DF05-0000-0000-C000-000000000046");
  108.                 Guid IID_WebBrowser = typeof(SHDocVw.WebBrowser).GUID;
  109.                 var IwebBrower = (SHDocVw.WebBrowser)IserviceProvider
  110.                  .QueryService(ref IID_IWebBrowserApp, ref IID_WebBrowser)
  111.                  ?? throw new Exception("IwebBrower == null");
  112.                 IwebBrower.BeforeNavigate2 += DWebBrowserEvents2_BeforeNavigate2EventHandler;
  113.                 IwebBrower.NewWindow2 += webBrower1_NewWindow2;
  114.                 IwebBrower.OnFullScreen += DWebBrowserEvents2_OnFullScreenEventHandler;

  115.                 IwebBrower.DownloadComplete += DWebBrowserEvents2_DownloadCompleteEventHandler;
  116.                 IwebBrower.DocumentComplete += DWebBrowserEvents2_DocumentCompleteEventHandler;
  117.             }
  118.             finally
  119.             {
  120.                 MyTextBlock.Text = MyTrace.AppendLine("Page_WebBrowser 2").ToString();
  121.                 MyTrace.Clear();
  122.             }
  123.         }
  124.         void DWebBrowserEvents2_DownloadCompleteEventHandler()
  125.         {
  126.             MyTrace.AppendLine("Download_Complete");
  127.         }
  128.         void DWebBrowserEvents2_DocumentCompleteEventHandler(
  129.          [In][MarshalAs(UnmanagedType.IDispatch)] object pDisp,
  130.          [In][MarshalAs(UnmanagedType.Struct)] ref object URL)
  131.         {
  132.             MyTrace.AppendLine("Document_Complete");
  133.         }
  134.         void DWebBrowserEvents2_BeforeNavigate2EventHandler(
  135.          [In][MarshalAs(UnmanagedType.IDispatch)] object pDisp,
  136.          [In][MarshalAs(UnmanagedType.Struct)] ref object URL,
  137.          [In][MarshalAs(UnmanagedType.Struct)] ref object Flags,
  138.          [In][MarshalAs(UnmanagedType.Struct)] ref object TargetFrameName,
  139.          [In][MarshalAs(UnmanagedType.Struct)] ref object PostData,
  140.          [In][MarshalAs(UnmanagedType.Struct)] ref object Headers,
  141.          [In][Out] ref bool Cancel)
  142.         {
  143.             MyTrace.AppendLine("BeforeNavigate2");
  144.         }
  145.         void webBrower1_NewWindow2(ref object ppDisp, ref bool Cancel)
  146.         {
  147.             MessageBox.Show("NewWindow2");
  148.         }
  149.         void DWebBrowserEvents2_OnFullScreenEventHandler(
  150.             [In] bool FullScreen)
  151.         {
  152.             MessageBox.Show("OnFullScreenEvent");
  153.         }
  154.         private void Button_Click(object sender, RoutedEventArgs e)
  155.         {
  156.             ((Button)sender).Background = Brushes.Red;
  157.             //MessageBox.Show($"goback={webBrowser1.CanGoBack} goforword={webBrowser1.CanGoForward}");
  158.             if (webBrowser1.CanGoBack)
  159.             {
  160.                 MyTrace.AppendLine("1 GoBack");
  161.                 webBrowser1.GoBack();
  162.                 MyTrace.AppendLine("2 GoBack");
  163.             }
  164.             else if (webBrowser1.CanGoForward)
  165.             {
  166.                 MyTrace.AppendLine("1 GoForward");
  167.                 webBrowser1.GoForward();
  168.                 MyTrace.AppendLine("2 GoForward");
  169.             }
  170.             else
  171.             {
  172.                 webBrowser1.Source = new Uri(
  173.                     "http://localhost:8080/MyWebPage/HtmlPage1.html");
  174.             }
  175.             MyTextBlock.Text =
  176.              MyTrace.AppendLine($"Button Press {++Count}").ToString();
  177.             MyTrace.Clear();
  178.         }
  179.     }
  180. }




  1. <Page x:Class="WpfLibrary_Hello.Page_WebView"
  2.       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.       xmlns:local="clr-namespace:WpfLibrary_Hello"
  7.       xmlns:Wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" 
  8.       mc:Ignorable="d" 
  9.       d:DesignHeight="450" d:DesignWidth="800"
  10.       Title="Page_WebView">
  11.     <DockPanel x:Name="MyStackPanel" LastChildFill="True">
  12.         <TextBox x:Name="MyTextBox"  
  13.                  Text="http://localhost:8080/MyWebPage/HtmlPage2.html" 
  14.                  Height="30"
  15.                  FontSize="22"
  16.                  DockPanel.Dock="Top" 
  17.                  KeyDown="MyTextBox_KeyDown"
  18.                  />

  19.         <Wpf:WebView2 x:Name="MyWebView2"
  20.             Source="http://localhost:8080/MyWebPage/HtmlPage2.html"/>
  21.     </DockPanel>
  22. </Page>
  23.     


  1. using Microsoft.Web.WebView2.Core;
  2. using Microsoft.Web.WebView2.Wpf;
  3. using System.Windows.Controls;
  4. using System.Windows.Input;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows;
  12. using System.Windows.Data;
  13. using System.Windows.Documents;
  14. using System.Windows.Media;
  15. using System.Windows.Media.Imaging;
  16. using System.Windows.Navigation;
  17. using System.Windows.Shapes;

  18. namespace WpfLibrary_Hello
  19. {
  20.     /// <summary>
  21.     /// Interaction logic for Page_WebView.xaml
  22.     /// </summary>
  23.     public partial class Page_WebView : Page
  24.     {
  25.         public Page_WebView()
  26.         {
  27.             InitializeComponent();
  28.             MyWebView2.SourceChanged += EventHandlerSourceChange;
  29.         }
  30.         void EventHandlerSourceChange(object? sender, CoreWebView2SourceChangedEventArgs e)
  31.         {
  32.             var s = sender as WebView2;
  33.             //if (e.IsNewDocument)
  34.             MyTextBox.Text = s?.Source.ToString();
  35.         }
  36.         private void MyTextBox_KeyDown(object sender, KeyEventArgs e)
  37.         {
  38.             if (e.Key == Key.Enter)
  39.             {
  40.                 MyWebView2.Source = new Uri(MyTextBox.Text);
  41.             }
  42.         }
  43.     }
  44. }





























  1. <!DOCTYPE html>

  2. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <h2>HtmlPage1.html</h2>
  9. </body>
  10. </html>





  1. <!DOCTYPE html>

  2. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6. </head>
  7. <body>
  8.     <p id="output-area">Some initial content in HTMLPage2</p>
  9.     <h3>This is HtmlPage2.html </h3>
  10.     <script>
  11.         const TargetElement = document.getElementById("output-area");
  12.         TargetElement.innerHTML = "location path = " +
  13.                         window.location.pathname;
  14.     </script>

  15. </body>
  16. </html>


































  1. <ResourceDictionary
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     xmlns:local="clr-namespace:WpfCustomControlLibrary_Hello">
  5.     <Style x:Key="Custom_Button_Chen" TargetType="Button">
  6.         <Setter Property="Template">
  7.             <Setter.Value>
  8.                 <ControlTemplate TargetType="Button">
  9.                     <Grid x:Name="Grid_Chen">
  10.                         <Border x:Name="bord_Chen"
  11.                         Background="{TemplateBinding Background}"
  12.                         BorderBrush="{TemplateBinding BorderBrush}"
  13.                         BorderThickness="{TemplateBinding BorderThickness}">
  14.                         </Border>
  15.                         <ContentPresenter HorizontalAlignment="Center" 
  16.                                       VerticalAlignment="Center"/>
  17.                     </Grid>
  18.                     <ControlTemplate.Triggers>
  19.                         <Trigger Property="IsMouseOver" Value="True" SourceName="Grid_Chen">
  20.                             <Setter TargetName="bord_Chen" Property="BorderBrush" Value="Red"/>
  21.                             <Setter TargetName="bord_Chen" Property="BorderThickness" Value="8"/>
  22.                             <Setter TargetName="bord_Chen" Property="Background" Value="Yellow"/>
  23.                         </Trigger>
  24.                     </ControlTemplate.Triggers>
  25.                 </ControlTemplate>
  26.             </Setter.Value>
  27.         </Setter>
  28.     </Style>

  29. </ResourceDictionary>





  1. <UserControl x:Class="WpfControlLibrary_Hello.Get_UserControl"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.         mc:Ignorable="d"
  8.         Height="450" Width="800">
  9.     <Grid>
  10.         <Border x:Name="MyBorder">
  11.             <ListBox SelectionChanged="selectionChange" 
  12.                      Height="200" Width="300" Foreground="Red" >
  13.                 <ListBoxItem>Binding Data Validation</ListBoxItem>
  14.                 <ListBoxItem>ListColorNames_class</ListBoxItem>
  15.                 <ListBoxItem>ListColorNames_item</ListBoxItem>
  16.                 <ListBoxItem>ListColorNames_label</ListBoxItem>
  17.                 <ListBoxItem>ListColorNames_string</ListBoxItem>
  18.                 <ListBoxItem>NumericUpDown</ListBoxItem>
  19.             </ListBox>
  20.         </Border>

  21.     </Grid>
  22. </UserControl>


  1. using System.Text;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using System.Windows.Data;
  5. using System.Windows.Documents;
  6. using System.Windows.Input;
  7. using System.Windows.Media;
  8. using System.Windows.Media.Imaging;
  9. using System.Windows.Navigation;
  10. using System.Windows.Shapes;

  11. namespace WpfControlLibrary_Hello
  12. {
  13.     /// <summary>
  14.     /// Interaction logic for UserControl1.xaml
  15.     /// </summary>
  16.     public partial class Get_UserControl : UserControl
  17.     {
  18.         public Get_UserControl()
  19.         {
  20.             InitializeComponent();
  21.         }
  22.         void selectionChange(object sender, SelectionChangedEventArgs e)
  23.         {
  24.             ListBox listBox = (ListBox)sender;
  25.             MyBorder.Child = listBox.SelectedIndex switch
  26.             {
  27.                 0 => new WpfControlLibrary_Hello.UserControl_Data_Validation(),
  28.                 1 => new WpfControlLibrary_Hello.UserControl_ListColorNames_class(),
  29.                 2 => new WpfControlLibrary_Hello.UserControl_ListColorNames_item(),
  30.                 3 => new WpfControlLibrary_Hello.UserControl_ListColorNames_label(),
  31.                 4 => new WpfControlLibrary_Hello.UserControl_ListColorNames_string(),
  32.                 5 => new WpfControlLibrary_Hello.UserControl_NumericUpDown(),
  33.                 _ => throw new ArgumentOutOfRangeException(),
  34.             };
  35.         }

  36.     }

  37. }


























  1. <Application x:Class="WpfApp_Hello.App"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:WpfApp_Hello"
  5.              StartupUri="MainWindow.xaml">
  6.     <Application.Resources>
  7.         <ResourceDictionary>
  8.             <ResourceDictionary.MergedDictionaries>
  9.                 <ResourceDictionary Source="/WpfApp_Hello;component/Dictionary1.xaml"/>
  10.                 <ResourceDictionary Source="/WpfApp_Hello;component/Dictionary2.xaml"/>
  11.                 <!--
  12.           <ResourceDictionary Source="/HelloWpfCustomControlLibrary;component/Themes/Generic.xaml"/>
  13.            -->
  14.                 <ResourceDictionary Source="pack://application:,,,/WpfCustomControlLibrary_Hello;component/Themes/Generic.xaml"/>
  15.             </ResourceDictionary.MergedDictionaries>
  16.         </ResourceDictionary>
  17.     </Application.Resources>
  18. </Application>


  1. using System.Windows;

  2. namespace WpfApp_Hello
  3. {
  4.     /// <summary>
  5.     /// Interaction logic for App.xaml
  6.     /// </summary>
  7.     public partial class App : Application
  8.     {
  9.         App()
  10.         {
  11.             MyViewModel.Trace.AppendLine("App()");
  12.         }
  13.         protected override void OnStartup(StartupEventArgs e)
  14.         {
  15.             base.OnStartup(e);
  16.             MyViewModel.Trace.AppendLine($"void OnStartup(StartupEventArgs e)");
  17.         }
  18.         protected override void OnExit(ExitEventArgs e)
  19.         {
  20.             //MessageBox.Show("OnExit");
  21.             base.OnExit(e);
  22.         }
  23.     }

  24. }




  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2.                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  3.     <Style x:Key="TextBlock_yellow" TargetType="TextBlock">
  4.         <Setter Property="Background" Value="Yellow"/>
  5.         <Setter Property="VerticalAlignment"  Value="Top"/>
  6.         <Setter Property="HorizontalAlignment" Value="Left"/>
  7.         <Setter Property="Width" Value="500"/>
  8.         <Setter Property="Height" Value="100"/>
  9.         <Setter Property="Margin" Value="5,10"/>
  10.         <Setter Property="TextWrapping" Value="Wrap" />
  11.     </Style>

  12.     <Style x:Key="TextBox_yellow" TargetType="TextBox">
  13.         <Setter Property="Background" Value="Yellow"/>
  14.         <Setter Property="HorizontalAlignment" Value="Left"/>
  15.         <Setter Property="VerticalAlignment"  Value="Top"/>
  16.         <Setter Property="Width" Value="500"/>
  17.         <Setter Property="Height" Value="100"/>
  18.         <Setter Property="Margin" Value="5,10"/>
  19.         <Setter Property="AcceptsReturn"  Value="True"/>
  20.         <Setter Property="TextWrapping" Value="Wrap"/>
  21.     </Style>

  22. </ResourceDictionary>    




  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2.                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.                     xmlns:local="clr-namespace:WpfApp_Hello"
  4.                     xmlns:system="clr-namespace:System;assembly=mscorlib">


  5.     <system:String x:Key="LocalizeMessage_Chen">en-USA</system:String>

  6.     <ControlTemplate x:Key="btnCustom" TargetType="Button">
  7.         <Border Name="border" Background="Green" 
  8.                 BorderThickness="2" BorderBrush="LightPink">
  9.             <Grid x:Name="MyGrid">
  10.                 <Ellipse x:Name="MyEllipse" 
  11.                          Fill="{TemplateBinding Background}" 
  12.                          Stroke="{TemplateBinding Foreground}"/>
  13.                 <ContentPresenter HorizontalAlignment="Center" 
  14.                                   VerticalAlignment="Center"/>
  15.             </Grid>
  16.         </Border>
  17.         <ControlTemplate.Triggers>
  18.             <Trigger Property="IsPressed" Value="True">
  19.                 <Setter TargetName="border" Property="Background" Value="Yellow"/>
  20.                 <Setter TargetName="border" Property="BorderBrush" Value="Black"/>
  21.             </Trigger>
  22.             <Trigger Property="IsMouseOver" Value="True" SourceName="MyGrid">
  23.                 <Setter TargetName="MyEllipse" Property="Stroke" Value="Red"/>
  24.                 <Setter TargetName="MyEllipse" Property="Fill" Value="Brown"/>
  25.             </Trigger>
  26.         </ControlTemplate.Triggers>
  27.     </ControlTemplate>
  28.     <ControlTemplate x:Key="btnCustom_StoryBoard" TargetType="{x:Type Button}">
  29.         <Border Name="border" Background="Green">
  30.             <Grid x:Name="MyGrid">
  31.                 <Ellipse x:Name="MyEllipse" 
  32.                          Fill="{TemplateBinding Background}" 
  33.                          Stroke="{TemplateBinding Foreground}"/>
  34.                 <ContentPresenter HorizontalAlignment="Left"
  35.                                   VerticalAlignment="Top"/>
  36.             </Grid>
  37.         </Border>
  38.         <ControlTemplate.Triggers>
  39.             <Trigger Property="IsPressed" Value="True">
  40.                 <Setter TargetName="border" Property="Background" Value="Yellow"/>
  41.             </Trigger>
  42.             <Trigger Property="IsMouseOver" Value="True" SourceName="MyGrid">
  43.                 <Setter TargetName="MyEllipse" Property="Stroke" Value="Red"/>
  44.                 <Trigger.EnterActions>
  45.                     <BeginStoryboard>
  46.                         <Storyboard>
  47.                             <ColorAnimation Storyboard.TargetName="MyEllipse" 
  48.                               Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
  49.                                             To="Brown" Duration="0:0:1"/>
  50.                         </Storyboard>
  51.                     </BeginStoryboard>
  52.                 </Trigger.EnterActions>
  53.                 <Trigger.ExitActions>
  54.                     <BeginStoryboard>
  55.                         <Storyboard>
  56.                             <ColorAnimation Storyboard.TargetName="MyEllipse" 
  57.                               Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
  58.                                             To="{x:Null}" Duration="0:0:0.1">
  59.                             </ColorAnimation>
  60.                         </Storyboard>
  61.                     </BeginStoryboard>
  62.                 </Trigger.ExitActions>
  63.             </Trigger>
  64.         </ControlTemplate.Triggers>
  65.     </ControlTemplate>
  66.     <Style x:Key="Custom_Button_Chen_XXX" TargetType="Button">
  67.         <Setter Property="Template">
  68.             <Setter.Value>
  69.                 <ControlTemplate TargetType="Button">
  70.                     <Grid x:Name="Grid_Chen">
  71.                         <Border x:Name="bord_Chen"
  72.                         Background="{TemplateBinding Background}"
  73.                         BorderBrush="{TemplateBinding BorderBrush}"
  74.                         BorderThickness="{TemplateBinding BorderThickness}">
  75.                         </Border>
  76.                         <ContentPresenter HorizontalAlignment="Center" 
  77.                                       VerticalAlignment="Center"/>
  78.                     </Grid>
  79.                     <ControlTemplate.Triggers>
  80.                         <Trigger Property="IsMouseOver" Value="True" SourceName="Grid_Chen">
  81.                             <Setter TargetName="bord_Chen" Property="BorderBrush" Value="Red"/>
  82.                             <Setter TargetName="bord_Chen" Property="BorderThickness" Value="8"/>
  83.                             <Setter TargetName="bord_Chen" Property="Background" Value="Yellow"/>
  84.                         </Trigger>
  85.                     </ControlTemplate.Triggers>
  86.                 </ControlTemplate>
  87.             </Setter.Value>
  88.         </Setter>
  89.     </Style>

  90. </ResourceDictionary>


  1. <Window x:Class="WpfApp_Hello.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:WpfApp_Hello"
  7.         xmlns:system="clr-namespace:System;assembly=mscorlib"
  8.         mc:Ignorable="d"
  9.         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  10.         WindowStyle="ThreeDBorderWindow"
  11.         ResizeMode="CanResizeWithGrip"
  12.         MinWidth="600" Height="600" Width="1024"
  13.         Title="MainWindow">
  14.     <Window.DataContext>
  15.         <Binding Source="{x:Static local:MainWindow.My_ViewModel}"/>
  16.     </Window.DataContext>
  17.     <Window.CommandBindings>
  18.         <CommandBinding Command="{x:Static local:MainWindow.InkCanVas_Command}" 
  19.                        CanExecute="InkCanVas_CanExecute"
  20.                        Executed="InkCanVas_Executed"/>
  21.         <CommandBinding Command="ApplicationCommands.Close" 
  22.                        Executed="Close_Executed"/>
  23.     </Window.CommandBindings>
  24.     <DockPanel x:Name="DockPanel_main">
  25.         <Menu Height="22" x:Name="MyMenu" DockPanel.Dock="Top">
  26.             <MenuItem Header="Common Commamds">
  27.                 <MenuItem Header="Paste" Command="ApplicationCommands.Paste"/>
  28.                 <MenuItem Header="Copy" Command="ApplicationCommands.Copy"/>
  29.                 <MenuItem Header="Open" Command="ApplicationCommands.Open"/>
  30.                 <Separator/>
  31.                 <MenuItem Header="Close" Command="ApplicationCommands.Close"/>
  32.             </MenuItem>
  33.             <MenuItem Header="Custom Commands" x:Name="MyMenuCmd">
  34.                 <MenuItem Header="InkCanVas" Command="{x:Static local:MainWindow.InkCanVas_Command}"/>
  35.                 <Separator/>
  36.             </MenuItem>
  37.         </Menu>
  38.         <TextBox x:Name="TextBox_Chen" Text="TextBox_Chen" 
  39.                  TextWrapping="Wrap" AcceptsReturn="True" >
  40.             <TextBox.InputBindings>
  41.                 <KeyBinding   Command="{Binding TextBox_KeyCommand_C_F1}" 
  42.                             CommandParameter="{Binding ElementName=TextBox_Chen}"
  43.                             Modifiers="Ctrl" Key="F1"/>
  44.                 <MouseBinding Command="{Binding TextBox_MouseCommand_DoubleClick}" 
  45.                             CommandParameter="{Binding ElementName=TextBox_Chen}"
  46.                             MouseAction="LeftDoubleClick" />
  47.             </TextBox.InputBindings>
  48.         </TextBox>
  49.     </DockPanel>
  50. </Window>


  1. using System.ComponentModel;
  2. using System.Data;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.IO.IsolatedStorage;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Xml.Serialization;

  14. namespace WpfApp_Hello
  15. {
  16.     public abstract class MyViewModelBase : UIElement, INotifyPropertyChanged
  17.     {
  18.         public event PropertyChangedEventHandler? PropertyChanged;
  19.         public void OnPropertyChanged(string myPropertyName)
  20.         {
  21.             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(myPropertyName));
  22.         }
  23.         public class RelayCommand : ICommand
  24.         {
  25.             public event EventHandler? CanExecuteChanged
  26.             {
  27.                 add => CommandManager.RequerySuggested += value;
  28.                 remove => CommandManager.RequerySuggested -= value;
  29.             }
  30.             public RelayCommand(Action<object?> execute) : this(execute, null) { }
  31.             public RelayCommand(Action<object?> execute, Predicate<object?>? canExecute)
  32.             {
  33.                 ArgumentNullException.ThrowIfNull(execute, "RelayCommand throw exception__CHen");
  34.                 _execute = execute; _canExecute = canExecute;
  35.             }
  36.             private readonly Action<object?> _execute;
  37.             private readonly Predicate<object?>? _canExecute;
  38.             public bool CanExecute(object? parameter)
  39.             {
  40.                 return _canExecute is null || _canExecute(parameter);
  41.             }
  42.             public void Execute(object? parameter)
  43.             {
  44.                 _execute(parameter);
  45.             }
  46.         }
  47.     }
  48.     public partial class MyViewModel : MyViewModelBase
  49.     {

  50.         public static readonly StringBuilder Trace = new();

  51.         public MyViewModel()
  52.         {
  53.             MyViewModel.Trace.AppendLine("public MyViewModel() ");
  54.         }
  55.         public MyViewModel(String str, Int32 In_int32)
  56.         {
  57.             MyViewModel.Trace.AppendLine($"public MyViewModel({str}, {In_int32})");
  58.         }
  59.         public static String About_WPF_feature()
  60.         {
  61.             StringBuilder WPF_feature = new("About WPF feature\n**************\n");
  62.             try
  63.             {
  64.                 System.Reflection.Assembly? assembly =
  65.                    typeof(MainWindow).Assembly ?? throw new Exception("assembly is null");
  66.                 //Assembly.GetEntryAssembly() ?? throw new Exception("assembly is null");
  67.                 string MainAssembly = $"{assembly.GetFiles()[0].Name}";
  68.                 WPF_feature.AppendLine(MainAssembly);
  69.                 String? XmalResource = System.Windows.Application.Current.TryFindResource(
  70.                        "LocalizeMessage_Chen") as String;
  71.                 WPF_feature.AppendLine("XmalResource LocalizeMessage_Chen=" + XmalResource);
  72.                 String query = "%AppData%";  //// "%SystemDrive%";
  73.                 String result = Environment.ExpandEnvironmentVariables(query);
  74.                 WPF_feature.AppendLine($"Result of query {query} = {result}");
  75.                 Type type = typeof(TextBox);
  76.                 PropertyMetadata MetaData = TextBox.TextProperty.GetMetadata(type);
  77.                 if (MetaData is FrameworkPropertyMetadata f)
  78.                 {
  79.                     WPF_feature.AppendLine($"{type.Name} DefaultUpdateSourceTrigger= {f?.DefaultUpdateSourceTrigger}");
  80.                 }
  81.             }
  82.             catch (Exception ex)
  83.             {
  84.                 MessageBox.Show("Error:" + ex.Message);
  85.             }
  86.             finally
  87.             {
  88.                 WPF_feature.AppendLine("*****************");
  89.             }
  90.             return WPF_feature.ToString();
  91.         }
  92.         private RelayCommand? _TextBox_MouseCommand_DoubleClick = null;
  93.         public ICommand TextBox_MouseCommand_DoubleClick
  94.         {
  95.             get
  96.             {
  97.                 _TextBox_MouseCommand_DoubleClick ??= new RelayCommand(
  98.                         Execute_TextBox_MouseCommand_DoubleClick);
  99.                 return _TextBox_MouseCommand_DoubleClick;
  100.             }
  101.         }
  102.         private RelayCommand? _TextBox_KeyCommand_C_F1 = null;
  103.         public ICommand TextBox_KeyCommand_C_F1
  104.         {
  105.             get
  106.             {
  107.                 _TextBox_KeyCommand_C_F1 ??= new RelayCommand(
  108.                         Execute_TextBox_KeyCommand_C_F1,
  109.                         CanExecute_TextBox_KeyCommand_C_F1);
  110.                 return _TextBox_KeyCommand_C_F1;
  111.             }
  112.         }
  113.         private void Execute_TextBox_KeyCommand_C_F1(object? parameter)
  114.         {
  115.             if (parameter is TextBox MyTextBox)
  116.             {
  117.                 MyTextBox.Foreground = new SolidColorBrush(SystemColors.AccentColor);
  118.                 MessageBox.Show($"Text.Length= {MyTextBox.Text.Length}");
  119.             }
  120.         }
  121.         private bool CanExecute_TextBox_KeyCommand_C_F1(object? parameter)
  122.         {
  123.             return true;
  124.         }
  125.         private void Execute_TextBox_MouseCommand_DoubleClick(object? parameter)
  126.         {
  127.             if (parameter is TextBox MyTextBox)
  128.             {
  129.                 MainWindow.AddText_And_MoveCursorToEnd(MyTextBox,
  130.                     "***\n" + MyViewModel.Trace.ToString());
  131.                 MyViewModel.Trace.Clear();
  132.             }
  133.         }
  134.     }
  135.     public partial class MainWindow : Window
  136.     {
  137.         public static MainWindow Singleton { get; set; }
  138.         static Action<MainWindow>? MyInitialActions = null;
  139.         class AddInitializationAction
  140.         {
  141.             public AddInitializationAction(Action<MainWindow> x)
  142.             {
  143.                 MainWindow.MyInitialActions += x;
  144.             }
  145.         }
  146.         public MainWindow()
  147.         {
  148.             InitializeComponent();

  149.             if (Singleton != null) throw new Exception("Singleton");
  150.             Singleton = this;
  151.             MyInitialWindowState.Begin(this);
  152.             MyInitialActions?.Invoke(this);

  153.             AddText_And_MoveCursorToEnd(TextBox_Chen,
  154.                 MyViewModel.About_WPF_feature() + MyViewModel.Trace.ToString());
  155.             MyViewModel.Trace.Clear();
  156.         }
  157.         static public void AddText_And_MoveCursorToEnd(TextBox txtbox, String text)
  158.         {
  159.             txtbox.Text += "\n" + text;
  160.             txtbox.CaretIndex = txtbox.Text.Length;
  161.             txtbox.Focus();
  162.             txtbox.ScrollToEnd();
  163.         }
  164.         static private MyViewModel my_viewModel = new MyViewModel();
  165.         static public MyViewModel My_ViewModel
  166.         {
  167.             get => my_viewModel;
  168.         }
  169.         protected override void OnClosing(CancelEventArgs e)
  170.         {
  171.             MyInitialWindowState.SaveInitialData(this);
  172.             base.OnClosing(e);
  173.         }
  174.         public void Close_Executed(object sender, RoutedEventArgs e)
  175.         {
  176.             this.Close();//Application.Current.Shutdown();
  177.         }
  178.     }

  179.     public class MyApp_Data
  180.     {
  181.         public Rect rect;
  182.         public WindowState windowState;
  183.     }
  184.     public class MyInitialWindowState
  185.     {
  186.         public static readonly IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetMachineStoreForAssembly();

  187.         public const string filenameIso = "MyIsolatedStorageFileName.iso";

  188.         static public void Begin(MainWindow x)
  189.         {
  190.             MyViewModel.Trace.AppendLine("Begin ===> isolatedStorageFile.GetFileNames ======");
  191.             foreach (String file in isolatedStorageFile.GetFileNames())
  192.             {
  193.                 MyViewModel.Trace.AppendLine(file);
  194.             }
  195.             MyViewModel.Trace.AppendLine("End   ===> isolatedStorageFile.GetFileNames ======");
  196.             if (isolatedStorageFile.FileExists(filenameIso))
  197.                 try
  198.                 {
  199.                     using var isolatedStorageFileStream =
  200.                           new IsolatedStorageFileStream(filenameIso,
  201.                               FileMode.Open, isolatedStorageFile);
  202.                     var xmlSerializer = new XmlSerializer(typeof(MyApp_Data));
  203.                     MyApp_Data? MyAppData =
  204.                           xmlSerializer.Deserialize(isolatedStorageFileStream) as MyApp_Data;
  205.                     if (MyAppData is not null)
  206.                     {
  207.                         x.Left = MyAppData.rect.Left;
  208.                         x.Top = MyAppData.rect.Top;
  209.                         x.Width = MyAppData.rect.Width;
  210.                         x.Height = MyAppData.rect.Height;
  211.                         x.WindowState = MyAppData.windowState == WindowState.Minimized ?
  212.                                  WindowState.Normal : MyAppData.windowState;
  213.                         //#if TRACE_Chen 
  214.                         var sw = new StringWriter();
  215.                         xmlSerializer.Serialize(sw, MyAppData);
  216.                         MyViewModel.Trace.AppendLine(sw.ToString());
  217.                         //#endif
  218.                     }
  219.                 }
  220.                 catch (Exception ex)
  221.                 {
  222.                     MessageBox.Show(ex.Message + "   " + filenameIso);
  223.                 }
  224.         }
  225.         static public void SaveInitialData(MainWindow x)
  226.         {
  227.             MyApp_Data MyAppData = new()
  228.             {
  229.                 rect = x.RestoreBounds,
  230.                 windowState = x.WindowState
  231.             };
  232.             try
  233.             {
  234.                 using var isolatedStorageFileStream =
  235.                      new IsolatedStorageFileStream(filenameIso,
  236.                           FileMode.Create, isolatedStorageFile);
  237.                 var xmlSerializer = new XmlSerializer(MyAppData.GetType());
  238.                 xmlSerializer.Serialize(isolatedStorageFileStream, MyAppData);

  239.             }
  240.             catch (Exception ex)
  241.             {
  242.                 MessageBox.Show(ex.Message + "   " + filenameIso);
  243.             }
  244.         }
  245.     }

  246.     [ValueConversion(typeof(string), typeof(Brush))]
  247.     public class MyStringToBrushConverter : IValueConverter
  248.     {

  249.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  250.         {
  251.             BrushConverter brushConverter = new();
  252.             object? MyObj = brushConverter.ConvertFromString((string)value);
  253.             if (MyObj is null) throw new NoNullAllowedException("MyStringToBrushConverter");
  254.             string? MyBrush = brushConverter.ConvertToInvariantString(MyObj);
  255.             //MessageBox.Show(MyBrush);
  256.             return MyObj;
  257.         }
  258.         public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  259.         {
  260.             throw new NotImplementedException("MyStringToBrushConverter ConvertBack");
  261.         }
  262.     }
  263.     [ValueConversion(typeof(string), typeof(DateTime))]
  264.     public class MyClockConverter : IValueConverter
  265.     {
  266.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  267.         {
  268.             if (value is DateTime) return String.Format((string)parameter, value);
  269.             throw new Exception("Error in MyClockConverter.Convert");
  270.         }
  271.         public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  272.         {
  273.             throw new NotImplementedException("MyClockConverter");
  274.         }
  275.     }
  276.     public class MyMultiValueConverter : IMultiValueConverter
  277.     {
  278.         public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  279.         {
  280.             return values.Clone();
  281.         }
  282.         public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  283.         {
  284.             throw new NotImplementedException("MyMultiValueConverter");
  285.         }

  286.     }
  287.     public class MyFormattedMultiTextConverter : IMultiValueConverter
  288.     {
  289.         public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  290.         {
  291.             return String.Format((String)parameter, values);
  292.         }
  293.         public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  294.         {
  295.             throw new NotImplementedException();
  296.         }
  297.     }
  298. }




  1. <Window x:Class="WpfApp_Hello.Window_Ink"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:WpfApp_Hello"
  7.         mc:Ignorable="d"
  8.         Title="Window_Ink" Height="486" Width="800" >
  9.     <StackPanel>
  10.         <ScrollViewer HorizontalScrollBarVisibility="Visible" >
  11.             <InkCanvas  Name="inkCanvas" Background="LemonChiffon" Width="3333" Height="333">
  12.                 <InkCanvas.DefaultDrawingAttributes>
  13.                     <DrawingAttributes/>
  14.                 </InkCanvas.DefaultDrawingAttributes>
  15.                 <Line Stroke="Red" X1="0" Y1="0" X2="333" Y2="333" Height="333" Width="681"/>
  16.                 <Line Stroke="Green" X1="3" Y1="333" X2="333" Y2="3"/>
  17.                 <Ellipse Stroke="Yellow" Width="33" Height="44" Fill="Green" Margin="123,123"/>
  18.             </InkCanvas>
  19.         </ScrollViewer>
  20.         <DockPanel LastChildFill="False" Height="20">
  21.             <RadioButton Content=" " Checked="RadioButton_Checked" Background="Red"/>
  22.             <RadioButton Content=" " Checked="RadioButton_Checked" Background="Green"/>
  23.             <RadioButton Content=" " Checked="RadioButton_Checked" Background="Blue"/>
  24.             <RadioButton Content="DefaultColor" Checked="RadioButton_Checked_4"/>
  25.         </DockPanel>
  26.         <UniformGrid Columns="3">
  27.             <Button Content="Open file" Width="80" Click="Button_Click_Open"/>
  28.             <Button Content="Save file" Width="160" Click="Button_Click_Save"/>
  29.         </UniformGrid>
  30.     </StackPanel>
  31. </Window>


  1. using Microsoft.Win32;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. using System.Windows.Controls;
  11. using System.Windows.Data;
  12. using System.Windows.Documents;
  13. using System.Windows.Ink;
  14. using System.Windows.Input;
  15. using System.Windows.Markup;
  16. using System.Windows.Media;
  17. using System.Windows.Media.Imaging;
  18. using System.Windows.Shapes;
  19. using System.Xml;
  20. using System.Xml.Serialization;
  21. namespace WpfApp_Hello
  22. {
  23.     /// <summary>
  24.     /// Interaction logic for Window_Ink.xaml
  25.     /// </summary>

  26.     public partial class Window_Ink : Window
  27.     {
  28.         public Window_Ink()
  29.         {
  30.             InitializeComponent();
  31.             defaultDrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone();
  32.         }
  33.         protected override void OnClosing(CancelEventArgs e)
  34.         {
  35.             MainWindow aa = (MainWindow)this.Owner;
  36.             aa.BOOL_CanExecuted_Ink = true;
  37.             aa.Activate();
  38.             base.OnClosing(e);
  39.         }

  40.         private void RadioButton_Checked(object sender, RoutedEventArgs e)
  41.         {
  42.             inkCanvas.DefaultDrawingAttributes.Color =
  43.            (System.Windows.Media.Color)ColorConverter.ConvertFromString(
  44.                ((RadioButton)e.Source).Background.ToString());
  45.         }
  46.         private readonly DrawingAttributes defaultDrawingAttributes;
  47.         private void RadioButton_Checked_4(object sender, RoutedEventArgs e)
  48.         {
  49.             inkCanvas.DefaultDrawingAttributes.Color = defaultDrawingAttributes.Color;
  50.         }

  51.         private void Button_Click_Open(object sender, RoutedEventArgs e)
  52.         {

  53.             var openFileDialog = new OpenFileDialog()
  54.             {
  55.                 CheckFileExists = true,
  56.                 Filter =
  57.               "Ink serialize fmt(*.isf)|*.isf|XAML(*.Xaml)|*.Xaml| All file (*.*)|*.*"
  58.             };
  59.             if (openFileDialog.ShowDialog(this) == true)
  60.                 try
  61.                 {
  62.                     if (openFileDialog.FilterIndex == 1)
  63.                         inkCanvas.Strokes = new System.Windows.Ink.StrokeCollection(
  64.                                          openFileDialog.OpenFile());
  65.                     else if (openFileDialog.FilterIndex == 2)
  66.                     {
  67.                         XmlReader xmlReader = XmlReader.Create(openFileDialog.OpenFile());
  68.                         inkCanvas.Strokes = XamlReader.Load(xmlReader) as StrokeCollection;
  69.                     }
  70.                     else throw new Exception(
  71.                        $"error:openFileDialog.FilterIndex={openFileDialog.FilterIndex}");
  72.                 }
  73.                 catch (Exception ex)
  74.                 {
  75.                     MessageBox.Show(ex.ToString());
  76.                 }
  77.         }
  78.         private void Button_Click_Save(object sender, RoutedEventArgs e)
  79.         {
  80.             var saveFileDialog = new SaveFileDialog
  81.             {
  82.                 OverwritePrompt = true,
  83.                 Filter =
  84.                 "Ink serialize fmt(*.isf)|*.isf|XAML(*.Xaml)|*.Xaml| All file (*.*)|*.*"
  85.             };

  86.             if (saveFileDialog.ShowDialog(this) == true)
  87.                 try
  88.                 {
  89.                     if (saveFileDialog.FilterIndex == 1)
  90.                         inkCanvas.Strokes.Save(saveFileDialog.OpenFile());
  91.                     else if (saveFileDialog.FilterIndex == 2)
  92.                         XamlWriter.Save(inkCanvas.Strokes, saveFileDialog.OpenFile());
  93.                     else throw new Exception(
  94.                        $"error:saveFileDialog.FilterIndex={saveFileDialog.FilterIndex}");
  95.                 }
  96.                 catch (Exception ex)
  97.                 {
  98.                     MessageBox.Show(ex.ToString());
  99.                 }
  100.         }
  101.     }
  102.     public partial class MainWindow
  103.     {
  104.         static private RoutedCommand? _InkCanVas_Command = null;
  105.         static public RoutedCommand InkCanVas_Command
  106.         {
  107.             get
  108.             {
  109.                 if (_InkCanVas_Command == null)
  110.                 {
  111.                     _InkCanVas_Command = new RoutedCommand();
  112.                 }
  113.                 return _InkCanVas_Command;
  114.             }
  115.         }
  116.         public bool BOOL_CanExecuted_Ink = true;
  117.         public void InkCanVas_CanExecute(object sender, CanExecuteRoutedEventArgs e)
  118.         {
  119.             e.CanExecute = BOOL_CanExecuted_Ink;
  120.         }
  121.         public void InkCanVas_Executed(object sender, RoutedEventArgs e)
  122.         {
  123.             Window_Ink w4 = new Window_Ink() { Owner = this };
  124.             w4.Show();
  125.             BOOL_CanExecuted_Ink = false;
  126.         }
  127.     }
  128. }




  1. <Window x:Class="WpfApp_Hello.Window1"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:WpfApp_Hello"
  7.         mc:Ignorable="d"
  8.         xmlns:system="clr-namespace:System;assembly=mscorlib"
  9.         WindowStyle="ThreeDBorderWindow"
  10.         ResizeMode="CanResizeWithGrip"
  11.         WindowStartupLocation="CenterOwner"
  12.         SizeToContent="Height"
  13.         Title="Window1" Height="600" Width="800">
  14.     <Window.Resources>
  15.         <local:MyFormattedMultiTextConverter x:Key="MyFormattedMultiTextConverterKey"/>
  16.         <local:MyClockConverter              x:Key="MyClockConverterKey"/>

  17.         <!--  <Style TargetType="Button"> -->
  18.         <Style TargetType="{x:Type Button}">
  19.             <Setter Property="Background" Value="#4E1A3D"/>
  20.             <Setter Property="Foreground" Value="White"/>
  21.             <Setter Property="BorderThickness" Value="5"/>
  22.             <Setter Property="BorderBrush">
  23.                 <Setter.Value>
  24.                     <LinearGradientBrush>
  25.                         <GradientStop Offset="0.0" Color="#4A1A3D"/>
  26.                         <GradientStop Offset="1.0" Color="Salmon"/>
  27.                     </LinearGradientBrush>
  28.                 </Setter.Value>
  29.             </Setter>
  30.         </Style>
  31.     </Window.Resources>
  32.     <Window.DataContext>
  33.         <Binding Source="{x:Static local:MainWindow.My_ViewModel}"/>
  34.     </Window.DataContext>

  35.     <StackPanel x:Name="MyStackPanel_w1">
  36.         <Label x:Name="MyLabel2" Height="23">
  37.             <Label.Content>
  38.                 <Binding Path="DateTime_Now" 
  39.                    Converter="{StaticResource MyClockConverterKey}"
  40.                    ConverterParameter=" {0:yyyy-MM-dd hh:mm:ss} " />
  41.             </Label.Content>
  42.         </Label>
  43.         <TextBlock  x:Name="MyTextBlock1" 
  44.             Background="{DynamicResource {x:Static SystemColors.AccentColorLight3BrushKey}}"
  45.             Foreground="{DynamicResource {x:Static SystemColors.AccentColorDark1BrushKey}}"
  46.             FontSize="14" FontFamily="Times New Roman"  
  47.             Height="25" >
  48.             <TextBlock.Text>
  49.                 <MultiBinding Converter="{StaticResource MyFormattedMultiTextConverterKey}"
  50.                               ConverterParameter=".Net Version:{0}  Now:{1}">
  51.                     <Binding Source="{x:Static system:Environment.Version}" />
  52.                     <Binding Path="DateTime_Now" 
  53.                              Converter="{StaticResource MyClockConverterKey}"
  54.                              ConverterParameter=" {0:yyyy-MM-dd hh:mm:ss} "/>
  55.                 </MultiBinding>
  56.             </TextBlock.Text>
  57.         </TextBlock>
  58.         <ScrollViewer HorizontalScrollBarVisibility="Auto" 
  59.                       VerticalScrollBarVisibility="Auto"  
  60.                       Height="450">
  61.             <TextBlock x:Name="MyTextBlock" Background="LightYellow" >
  62.                 <TextBlock.Text>
  63.                     <MultiBinding Converter="{StaticResource MyFormattedMultiTextConverterKey}"
  64.                               ConverterParameter="{}{0}
  65.                                   &#10; SystemDirectory:{1}
  66.                                   &#10; UserName:{2}
  67.                                   &#10; Today:{3:d MMM,yyyy}
  68.                                   &#10; {4}
  69.                               " >
  70.                         <Binding Path="DateTime_Now_Ticks" />
  71.                         <Binding Source="{x:Static system:Environment.SystemDirectory}" />
  72.                         <Binding Source="{x:Static system:Environment.UserName}" />
  73.                         <Binding Source="{x:Static system:DateTime.Today}" />
  74.                         <Binding Source="{x:Static local:CodeFromXaml.Resource1String}"/>
  75.                     </MultiBinding>
  76.                 </TextBlock.Text>
  77.                 <TextBlock.ContextMenu>
  78.                     <ContextMenu MenuItem.Click="ContextMenu_Click">
  79.                         <HeaderedContentControl Header="Red" Foreground="Red"/>
  80.                         <HeaderedContentControl Header="Green" Foreground="Green"/>
  81.                         <HeaderedContentControl Header="Orange" Foreground="Orange"/>
  82.                     </ContextMenu>
  83.                 </TextBlock.ContextMenu>

  84.             </TextBlock>
  85.         </ScrollViewer>

  86.         <!--
  87.         <x:Code>
  88.             <![CDATA[
  89.           private void RadioButton2_Checked_inline(object sender, RoutedEventArgs e)
  90.           {
  91.           }
  92.        ]]>
  93.         </x:Code>
  94.         -->
  95.     </StackPanel>
  96. </Window>
  97.     


  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Shapes;
  15. using System.Windows.Threading;

  16. namespace WpfApp_Hello
  17. {
  18.     public partial class MainWindow
  19.     {
  20.         AddInitializationAction WW1 =
  21.              new(Window1.my_menu.MyInitialActions);
  22.     }
  23.     public partial class Window1 : Window, ICreateWindow
  24.     {
  25.         public static Add_Menu_Item<Window1> my_menu = new("Window1");
  26.         void ICreateWindow.MyShow()
  27.         {
  28.             Owner = my_menu.OwnerWindow;
  29.             Show();
  30.             my_menu.CanExecuted = false;
  31.         }
  32.         public Window1()
  33.         {
  34.             InitializeComponent();
  35.             MyInitialization();
  36.         }

  37.         protected override void OnClosing(CancelEventArgs e)
  38.         {
  39.             my_menu.CanExecuted = true;
  40.             base.OnClosing(e);
  41.         }
  42.         Style? buttonStyle0;
  43.         Style? buttonStyle1;
  44.         bool buttonStyleSwitch = false;

  45.         void MyInitialization()
  46.         {
  47.             var btn = new Button
  48.             {
  49.                 Content = Btn_Content1
  50.             };
  51.             btn.Click += Button_Click;
  52.             buttonStyle0 = btn.Style;
  53.             MyStackPanel_w1.Children.Add(btn);
  54.             buttonStyle1 = btn.Style;

  55.             (new DispatcherTimer(
  56.                 TimeSpan.FromSeconds(1),
  57.                 DispatcherPriority.Normal,
  58.                 TimerOnTick,
  59.                 Dispatcher.CurrentDispatcher)
  60.             ).Start();
  61.         }
  62.         void TimerOnTick(object? sender, EventArgs e)
  63.         {
  64.             MainWindow.My_ViewModel.DateTime_Now = DateTime.Now;
  65.         }
  66.         const string Btn_Content0 = "Orignal Buttton style";
  67.         const string Btn_Content1 = "implicit key in resource";
  68.         void Button_Click(object sender, RoutedEventArgs e)
  69.         {
  70.             Button btn = (Button)sender;
  71.             buttonStyleSwitch = !buttonStyleSwitch;
  72.             btn.Content = buttonStyleSwitch ? Btn_Content0 : Btn_Content1;
  73.             btn.Style = buttonStyleSwitch ? buttonStyle0 : buttonStyle1;
  74.             MainWindow.My_ViewModel.DateTime_Now_Ticks = $"--- {DateTime.Now.Ticks} ----";
  75.         }
  76.         void ContextMenu_Click(object sender, RoutedEventArgs e)
  77.         {
  78.             MenuItem? menuItem = e.OriginalSource as MenuItem;
  79.             HeaderedContentControl? headeredContentControl = menuItem?.Header as HeaderedContentControl;
  80.             if (headeredContentControl?.Header is String str)
  81.             {
  82.                 System.Windows.Media.Color color = (System.Windows.Media.Color)
  83.                     System.Windows.Media.ColorConverter.ConvertFromString(str);
  84.                 MyTextBlock.Foreground = new SolidColorBrush(color);
  85.             }
  86.         }
  87.     }
  88.     public interface ICreateWindow
  89.     {
  90.         void MyShow();
  91.     }
  92.     public class Add_Menu_Item<WIN> where WIN : ICreateWindow, new()
  93.     {
  94.         String MyHeader;
  95.         bool BOOL_CanExecuted = true;
  96.         public bool CanExecuted
  97.         {
  98.             get => BOOL_CanExecuted;
  99.             set => BOOL_CanExecuted = value;
  100.         }
  101.         public Add_Menu_Item(String Header)
  102.         {
  103.             MyHeader = Header;
  104.         }

  105.         public Window? OwnerWindow;
  106.         public void MyInitialActions(MainWindow mainWindow)
  107.         {
  108.             OwnerWindow = mainWindow;
  109.             var Routed_Command = new RoutedCommand();

  110.             mainWindow.MyMenuCmd.Items.Add(
  111.                 new MenuItem()
  112.                 {
  113.                     Header = MyHeader,
  114.                     Command = Routed_Command
  115.                 }
  116.             );
  117.             mainWindow.CommandBindings.Add(
  118.                 new CommandBinding
  119.                 (
  120.                       Routed_Command,
  121.                       CreateWindow_Executed,
  122.                       CreateWindow_CanExecute
  123.                 )
  124.             );
  125.         }
  126.         void CreateWindow_CanExecute(object sender, CanExecuteRoutedEventArgs e)
  127.         {
  128.             e.CanExecute = CanExecuted;
  129.         }
  130.         void CreateWindow_Executed(object sender, RoutedEventArgs e)
  131.         {
  132.             (new WIN()).MyShow();
  133.         }
  134.     }

  135.     public partial class MyViewModel
  136.     {
  137.         public DateTime DateTime_Now
  138.         {
  139.             get { return (DateTime)GetValue(DateTime_NowProperty); }
  140.             set { SetValue(DateTime_NowProperty, value); }
  141.         }
  142.         public event RoutedPropertyChangedEventHandler<DateTime> DateTimeChanged
  143.         {
  144.             add { AddHandler(DateTimeChangedEvent, value); }
  145.             remove { RemoveHandler(DateTimeChangedEvent, value); }
  146.         }
  147.         static readonly DependencyProperty DateTime_NowProperty =
  148.             DependencyProperty.Register(
  149.                 nameof(DateTime_Now), typeof(DateTime), typeof(MyViewModel),
  150.                 new FrameworkPropertyMetadata(DateTime.Now,
  151.                 new PropertyChangedCallback(OnDateTimeChangedCallback))
  152.             );
  153.         static readonly RoutedEvent DateTimeChangedEvent =
  154.          EventManager.RegisterRoutedEvent(
  155.                nameof(DateTimeChanged), RoutingStrategy.Bubble,
  156.                typeof(RoutedPropertyChangedEventHandler<DateTime>),
  157.                typeof(MyViewModel)
  158.          );
  159.         static void OnDateTimeChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs args)
  160.         {
  161.             var DateTimeObj = (MyViewModel)obj;
  162.             var e = new RoutedPropertyChangedEventArgs<DateTime>(
  163.                   (DateTime)args.OldValue, (DateTime)args.NewValue,
  164.                   DateTimeChangedEvent
  165.             );
  166.             DateTimeObj.OnDateTimeChanged(e);
  167.         }
  168.         protected virtual void OnDateTimeChanged(RoutedPropertyChangedEventArgs<DateTime> args)
  169.         {
  170.             RaiseEvent(args);
  171.         }
  172.         String _DateTime_Now_Ticks = "My type name is " +
  173.            nameof(MainWindow.My_ViewModel.DateTime_Now_Ticks);
  174.         public String DateTime_Now_Ticks
  175.         {
  176.             get => _DateTime_Now_Ticks;
  177.             set
  178.             {
  179.                 _DateTime_Now_Ticks = value;
  180.                 OnPropertyChanged(nameof(DateTime_Now_Ticks));
  181.             }
  182.         }
  183.     }
  184.     public partial class CodeFromXaml
  185.     {
  186.         public static String Resource1String
  187.         {
  188.             get =>
  189.          @"
  190.            public partial class App : System.Windows.Application {
  191.         
  192.         private bool _contentLoaded;
  193.         
  194.         /// <summary>
  195.         /// InitializeComponent
  196.         /// </summary>
  197.         [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  198.         [System.CodeDom.Compiler.GeneratedCodeAttribute(""PresentationBuildTasks"", ""9.0.8.0"")]
  199.         public void InitializeComponent() {
  200.             if (_contentLoaded) {
  201.                 return;
  202.             }
  203.             _contentLoaded = true;
  204.             
  205.             #line 5 ""..\..\..\..\App.xaml""
  206.             this.StartupUri = new System.Uri(""MainWindow.xaml"", System.UriKind.Relative);
  207.             
  208.             #line default
  209.             #line hidden
  210.             System.Uri resourceLocater = new System.Uri(""/WpfApp_Hello;component/app.xaml"", System.UriKind.Relative);
  211.             
  212.             #line 1 ""..\..\..\..\App.xaml""
  213.             System.Windows.Application.LoadComponent(this, resourceLocater);
  214.             
  215.             #line default
  216.             #line hidden
  217.         }
  218.         
  219.         /// <summary>
  220.         /// Application Entry Point.
  221.         /// </summary>
  222.         [System.STAThreadAttribute()]
  223.         [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  224.         [System.CodeDom.Compiler.GeneratedCodeAttribute(""PresentationBuildTasks"", ""9.0.8.0"")]
  225.         public static void Main() {
  226.             WpfApp_Hello.App app = new WpfApp_Hello.App();
  227.             app.InitializeComponent();
  228.             app.Run();
  229.         }
  230.     }
  231.   
  232.          ";
  233.         }
  234.     }

  235. }




  1. <Window x:Class="WpfApp_Hello.Window2"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:WpfApp_Hello"
  7.         mc:Ignorable="d"
  8.         Title="Window2">
  9.     <Window.Resources>
  10.         <local:MyMultiValueConverter x:Key="MyMultiValueConverterKey"/>
  11.     </Window.Resources>
  12.     <Window.DataContext>
  13.         <Binding Source="{x:Static local:MainWindow.My_ViewModel}"/>
  14.     </Window.DataContext>
  15.     <Grid>
  16.         <Grid.ColumnDefinitions>
  17.             <ColumnDefinition Width="*"/>
  18.             <ColumnDefinition Width="*"/>
  19.         </Grid.ColumnDefinitions>
  20.         <StackPanel Grid.Column="0">
  21.             <TextBlock Style="{StaticResource TextBlock_yellow}">
  22.                 <TextBlock.Text>
  23.                     <Binding Path="Text_MVVM_PropertyChanged"/>
  24.                 </TextBlock.Text>
  25.             </TextBlock>

  26.             <TextBlock Text="{Binding Path=Text_MVVM1_Explicit}" 
  27.                     Style="{StaticResource TextBlock_yellow}" />
  28.             <TextBlock Text="{Binding Path=Text_MVVM2_Explicit}" 
  29.                     Style="{StaticResource TextBlock_yellow}" />
  30.         </StackPanel>

  31.         <StackPanel  Grid.Column="1">
  32.             <TextBox Style="{StaticResource TextBox_yellow}" 
  33.                   Text="{Binding Path=Text_MVVM_PropertyChanged,
  34.                                  UpdateSourceTrigger=PropertyChanged}" 
  35.          />
  36.             <TextBox x:Name="MyTextBox_1"
  37.                   Style="{StaticResource  TextBox_yellow}"  
  38.                   Text="{Binding Path=Text_MVVM1_Explicit,
  39.                                  UpdateSourceTrigger=Explicit}"
  40.                   TextChanged="MyTextBox_1_TextChanged"
  41.                   
  42.          />
  43.             <TextBox x:Name="MyTextBox_2"
  44.                   Style="{StaticResource  TextBox_yellow}"  
  45.                   TextChanged="MyTextBox_2_TextChanged"
  46.                   >
  47.                 <TextBox.Text>
  48.                     <Binding Path="Text_MVVM2_Explicit" 
  49.                           UpdateSourceTrigger="Explicit"/>
  50.                 </TextBox.Text>
  51.             </TextBox>
  52.             <Button x:Name="ExplicitButton" Content="Explicit"  
  53.               Command="{Binding Command_ExplicitButton}"
  54.               Background="Yellow" IsEnabled="False" 
  55.               Margin="100,10" Height="40" Width="150">
  56.                 <Button.CommandParameter>
  57.                     <MultiBinding Converter="{StaticResource MyMultiValueConverterKey}">
  58.                         <Binding ElementName="ExplicitButton"/>
  59.                         <Binding ElementName="MyTextBox_1"/>
  60.                         <Binding ElementName="MyTextBox_2"/>
  61.                     </MultiBinding>
  62.                 </Button.CommandParameter>
  63.             </Button>
  64.         </StackPanel>
  65.     </Grid>
  66. </Window>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Shapes;
  15. namespace WpfApp_Hello
  16. {
  17.     public partial class MainWindow
  18.     {
  19.         AddInitializationAction WW2 =
  20.              new(Window2.my_menu.MyInitialActions);
  21.     }
  22.     public partial class Window2 : Window, ICreateWindow
  23.     {
  24.         public static Add_Menu_Item<Window2> my_menu = new("Window2");
  25.         void ICreateWindow.MyShow()
  26.         {
  27.             Owner = my_menu.OwnerWindow;
  28.             Show();
  29.             my_menu.CanExecuted = false;
  30.         }
  31.         public Window2()
  32.         {
  33.             InitializeComponent();
  34.         }
  35.         protected override void OnClosing(CancelEventArgs e)
  36.         {
  37.             my_menu.CanExecuted = true;
  38.             base.OnClosing(e);
  39.         }
  40.         private void MyTextBox_1_TextChanged(object sender, TextChangedEventArgs e)
  41.         {
  42.             if (ExplicitButton is not null)
  43.                 ExplicitButton.IsEnabled = true;
  44.         }
  45.         private void MyTextBox_2_TextChanged(object sender, TextChangedEventArgs e)
  46.         {
  47.             if (ExplicitButton is not null)
  48.                 ExplicitButton.IsEnabled = true;
  49.         }
  50.     }
  51.     public partial class MyViewModel : MyViewModelBase
  52.     {
  53.         RelayCommand? _Command_ExplicitButton = null;
  54.         public ICommand Command_ExplicitButton
  55.         {
  56.             get
  57.             {
  58.                 _Command_ExplicitButton ??=
  59.                     new RelayCommand(Execute_ExplicitButton);
  60.                 return _Command_ExplicitButton;
  61.             }
  62.         }
  63.         private void Execute_ExplicitButton(object? parameter)
  64.         {
  65.             object[]? objects = parameter as object[];
  66.             Button? Explicit_Button = objects?[0] as Button;
  67.             TextBox? MyTextBox_1 = objects?[1] as TextBox;
  68.             TextBox? MyTextBox_2 = objects?[2] as TextBox;
  69.             MyTextBox_1?.GetBindingExpression(TextBox.TextProperty).
  70.                          UpdateSource();
  71.             {
  72.                 BindingExpression? bindingExpression_2 =
  73.                   MyTextBox_2?.GetBindingExpression(TextBox.TextProperty);
  74.                 bindingExpression_2?.UpdateSource();
  75.             }
  76.             if (Explicit_Button is not null) Explicit_Button.IsEnabled = false;
  77.         }

  78.         private String _Text_MVVM_PropertyChanged = "PropertyChanged >>";
  79.         private String _Text_MVVM1_Explicit = "Explicit 1>>";
  80.         private String _Text_MVVM2_Explicit = "Explicit 2>>";
  81.         public String Text_MVVM_PropertyChanged
  82.         {
  83.             get => _Text_MVVM_PropertyChanged;
  84.             set
  85.             {
  86.                 _Text_MVVM_PropertyChanged = value;
  87.                 OnPropertyChanged(nameof(Text_MVVM_PropertyChanged));
  88.             }
  89.         }
  90.         public String Text_MVVM1_Explicit
  91.         {
  92.             get => _Text_MVVM1_Explicit;
  93.             set
  94.             {
  95.                 _Text_MVVM1_Explicit = value;
  96.                 OnPropertyChanged(nameof(Text_MVVM1_Explicit));
  97.             }
  98.         }
  99.         public String Text_MVVM2_Explicit
  100.         {
  101.             get => _Text_MVVM2_Explicit;
  102.             set
  103.             {
  104.                 _Text_MVVM2_Explicit = value;
  105.                 OnPropertyChanged(nameof(Text_MVVM2_Explicit));
  106.             }
  107.         }
  108.     }
  109. }




  1. <Window x:Class="WpfApp_Hello.Window3"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:MySystem="clr-namespace:System;assembly=mscorlib"
  7.         xmlns:local="clr-namespace:WpfApp_Hello"
  8.         mc:Ignorable="d"
  9.         Title="Window3" Width="1024">
  10.     <Window.DataContext>
  11.         <Binding Source="{x:Static local:MainWindow.My_ViewModel}"/>
  12.     </Window.DataContext>
  13.     <StackPanel >
  14.         <TextBlock Name="TextBlock_W3" 
  15.                Background="Bisque"  Height="100" Margin="8"
  16.                Text="{x:Static  MySystem:Environment.MachineName}">
  17.         </TextBlock>
  18.         <TextBox x:Name="MyTextBox1" AcceptsReturn="True"
  19.                   TextWrapping="Wrap" Height="100" Margin="8">
  20.             <TextBox.Text>
  21.                 <x:Static  Member="MySystem:Environment.MachineName"/>
  22.             </TextBox.Text>
  23.         </TextBox>
  24.         <Label 
  25.            Foreground="Green" Height="30" Width="300" Margin="8">
  26.             <Label.BorderBrush>Yellow</Label.BorderBrush>
  27.             <Label.BorderThickness>3</Label.BorderThickness>
  28.             <Label.Background>
  29.                 <Binding Path="ColorName" 
  30.               Converter="{x:Static  local:Window3.My_StringToBrushConverter}" />
  31.             </Label.Background>
  32.             <Label.Content>
  33.                 <x:Static  Member="MySystem:Environment.SystemDirectory"/>
  34.             </Label.Content>
  35.         </Label>
  36.         <Button Content="Test Binding" Click="Button_Click"  
  37.             Width="200" Height="41" Margin="8" >
  38.         </Button>
  39.         <Label Content ="{x:Static MySystem:Environment.SystemDirectory}"
  40.            Foreground="Green" Height="30" Width="300" Margin="8"
  41.            x:Name="MyLabel_3">
  42.             <Label.BorderBrush>Yellow</Label.BorderBrush>
  43.             <Label.BorderThickness>3</Label.BorderThickness>
  44.         </Label>
  45.         <Grid Margin="11,11">
  46.             <Button Template="{StaticResource btnCustom}" Background="Gold" 
  47.             HorizontalAlignment="Left" Width="100" Height="50" 
  48.             Content="Custom button" Click="Button_Click"
  49.         >
  50.                 <Button.ToolTip>
  51.                     <TextBlock> ToolTip</TextBlock>
  52.                 </Button.ToolTip>
  53.             </Button>
  54.             <Button Template="{StaticResource btnCustom_StoryBoard}" Foreground="Blue"
  55.             HorizontalAlignment="Center" Width="200" Height="50" 
  56.             Content="Test StoryBoard"
  57.     />
  58.             <Button Style="{StaticResource Custom_Button_Chen}" 
  59.             HorizontalAlignment="Right" Width="200" Height="50" 
  60.             BorderBrush="HotPink"
  61.             BorderThickness="5"
  62.             Background="DarkGoldenrod"
  63.             Content="Custom_Button_Chen OK" Click="Button_Click"
  64.     />
  65.         </Grid>
  66.     </StackPanel>
  67. </Window>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Shapes;

  15. namespace WpfApp_Hello
  16. {
  17.     public partial class MainWindow
  18.     {
  19.         AddInitializationAction WW3 =
  20.              new(Window3.my_menu.MyInitialActions);
  21.     }
  22.     public partial class Window3 : Window, ICreateWindow
  23.     {
  24.         public static Add_Menu_Item<Window3> my_menu = new("Window3");
  25.         void ICreateWindow.MyShow()
  26.         {
  27.             Owner = my_menu.OwnerWindow;
  28.             Show();
  29.             my_menu.CanExecuted = false;

  30.         }
  31.         public Window3()
  32.         {
  33.             InitializeComponent();
  34.         }
  35.         protected override void OnClosing(CancelEventArgs e)
  36.         {
  37.             my_menu.CanExecuted = true;
  38.             base.OnClosing(e);
  39.         }

  40.         private static MyStringToBrushConverter _My_StringToBrushConverter = new();
  41.         public static MyStringToBrushConverter My_StringToBrushConverter
  42.         {
  43.             get => _My_StringToBrushConverter;
  44.         }
  45.         private static MyViewModel _MyViewModelKey_XXX = new("Blue", 789);
  46.         public static MyViewModel MyViewModelKey_XXX
  47.         {
  48.             get => _MyViewModelKey_XXX;
  49.         }

  50.         String[] MyCOLOR = ["Red", "Black", "YellowGreen"];
  51.         UInt32 ColorIndex = 0;

  52.         MyViewModel? MyViewModelObject = null;
  53.         Binding? MyBinding1;
  54.         Binding? MyBinding2;
  55.         Binding? MyBinding3;
  56.         BindingExpressionBase? bindingExpressionBase1;
  57.         BindingExpressionBase? bindingExpressionBase2;
  58.         BindingExpressionBase? bindingExpressionBase3;
  59.         private void Button_Click(object sender, RoutedEventArgs e)
  60.         {
  61.             if (MyViewModelObject == null)
  62.             {
  63.                 MyViewModelObject = new();
  64.                 MyBinding1 = new(nameof(MyViewModel.ColorName))
  65.                 {
  66.                     Source = MyViewModelObject,
  67.                     Converter = new MyStringToBrushConverter()
  68.                 };
  69.                 bindingExpressionBase1 =
  70.                    MyLabel_3.SetBinding(Label.BackgroundProperty, MyBinding1);
  71.                 if (bindingExpressionBase1.HasError)
  72.                     MessageBox.Show("bindingExpressionBase1.ValidationError");
  73.                 //--------------------------------------------------
  74.                 MyBinding2 = new(nameof(MyViewModel.MyText3))
  75.                 {
  76.                     Source = MyViewModelObject,
  77.                     Mode = BindingMode.TwoWay,
  78.                     UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
  79.                     //UpdateSourceTrigger = UpdateSourceTrigger.LostFocus
  80.                 };
  81.                 bindingExpressionBase2 =
  82.                    MyTextBox1.SetBinding(TextBox.TextProperty, MyBinding2);
  83.                 if (bindingExpressionBase2.HasError)
  84.                     MessageBox.Show("bindingExpressionBase2.ValidationError");
  85.                 //----------------------------------------------------
  86.                 MyBinding3 = new(nameof(MyViewModel.MyText3))
  87.                 {
  88.                     Source = MyViewModelObject
  89.                 };
  90.                 bindingExpressionBase3 = TextBlock_W3.SetBinding(TextBlock.TextProperty, MyBinding3);
  91.                 if (bindingExpressionBase3.HasError)
  92.                     MessageBox.Show("bindingExpressionBase2.ValidationError");
  93.             }
  94.             if (++ColorIndex >= MyCOLOR.Length) ColorIndex = 0;
  95.             MainWindow.My_ViewModel.ColorName = MyCOLOR[ColorIndex];
  96.             MyViewModelObject.ColorName = MyCOLOR[ColorIndex];
  97.             MyViewModelObject.MyText3 = $"{DateTime.Now.Ticks}  Tow way";
  98.         }
  99.     }
  100.     public partial class MyViewModel : MyViewModelBase
  101.     {

  102.         private string _ColorName = "#FF800080";
  103.         public String ColorName
  104.         {
  105.             get { return _ColorName; }
  106.             set
  107.             {
  108.                 _ColorName = value;
  109.                 OnPropertyChanged(nameof(ColorName));
  110.             }
  111.         }
  112.         private String _MyText3 = string.Empty;
  113.         public String MyText3
  114.         {
  115.             get => _MyText3;
  116.             set
  117.             {
  118.                 _MyText3 = value;
  119.                 OnPropertyChanged(nameof(MyText3));
  120.             }
  121.         }
  122.     }
  123. }




  1. <Window x:Class="WpfApp_Hello.Window4"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:WpfApp_Hello"
  7.         xmlns:MyControls="clr-namespace:WpfControlLibrary_Hello;assembly=WpfControlLibrary_hello"
  8.         mc:Ignorable="d"
  9.         Title="Window4" Height="450" Width="800">
  10.     <Grid>
  11.         <MyControls:Get_UserControl Background="LightBlue"/>
  12.     </Grid>
  13. </Window>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Shapes;

  15. namespace WpfApp_Hello
  16. {
  17.     public partial class MainWindow
  18.     {
  19.         AddInitializationAction WW4 =
  20.              new(Window4.my_menu.MyInitialActions);
  21.     }
  22.     public partial class Window4 : Window, ICreateWindow
  23.     {
  24.         public static Add_Menu_Item<Window4> my_menu = new("UserControl");
  25.         void ICreateWindow.MyShow()
  26.         {
  27.             Owner = my_menu.OwnerWindow;
  28.             Show();
  29.             my_menu.CanExecuted = false;
  30.         }
  31.         public Window4()
  32.         {
  33.             InitializeComponent();
  34.         }
  35.         protected override void OnClosing(CancelEventArgs e)
  36.         {
  37.             my_menu.CanExecuted = true;
  38.             MainWindow aa = (MainWindow)this.Owner;
  39.             aa.Activate();
  40.             base.OnClosing(e);
  41.         }
  42.     }
  43. }










  1. <UserControl x:Class="WpfControlLibrary_Hello.UserControl_Data_Validation"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.              mc:Ignorable="d" 
  8.                     xmlns:system="clr-namespace:System;assembly=mscorlib"
  9.              d:DesignHeight="450" d:DesignWidth="800">
  10.     <UserControl.Resources>
  11.         <Style TargetType="{x:Type TextBox}" x:Key="textBoxInError">
  12.             <Setter Property="Validation.ErrorTemplate">
  13.                 <Setter.Value>
  14.                     <ControlTemplate>
  15.                         <DockPanel>
  16.                             <Border BorderBrush="OrangeRed" BorderThickness="4">
  17.                                 <AdornedElementPlaceholder x:Name="MyAdorner"/>
  18.                             </Border>
  19.                             <Expander ExpandDirection="Right">
  20.                                 <Grid>
  21.                                     <Rectangle Stroke="Blue" Fill="PaleVioletRed"/>
  22.                                     <TextBlock Text="{Binding 
  23.                                     ElementName=MyAdorner,
  24.                                     Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"
  25.                                  />
  26.                                 </Grid>
  27.                             </Expander>
  28.                         </DockPanel>
  29.                     </ControlTemplate>
  30.                 </Setter.Value>
  31.             </Setter>
  32.             <Style.Triggers>
  33.                 <Trigger Property="Validation.HasError" Value="true">
  34.                     <Setter 
  35.                         Property="ToolTip"
  36.                         Value="{Binding 
  37.                          RelativeSource={x:Static RelativeSource.Self},
  38.                          Path=(Validation.Errors)[0].ErrorContent}"/>
  39.                     <Setter Property="Background" Value="DarkSalmon"/>
  40.                 </Trigger>
  41.                 <Trigger Property="Validation.HasError" Value="false">
  42.                     <Setter Property="ToolTip" Value="OK"/>
  43.                 </Trigger>
  44.             </Style.Triggers>
  45.         </Style>
  46.     </UserControl.Resources>
  47.     <Grid>
  48.         <Grid.RowDefinitions>
  49.             <RowDefinition/>
  50.             <RowDefinition/>
  51.         </Grid.RowDefinitions>
  52.         <Grid.ColumnDefinitions>
  53.             <ColumnDefinition/>
  54.             <ColumnDefinition/>
  55.         </Grid.ColumnDefinitions>
  56.         <TextBox Style="{StaticResource textBoxInError}"
  57.         Width="100"  Height="30"
  58.         BorderThickness="2" BorderBrush="SpringGreen"
  59.      >
  60.             <TextBox.Text>
  61.                 <Binding 
  62.            RelativeSource="{
  63.              RelativeSource FindAncestor, 
  64.              AncestorType={x:Type local:UserControl_Data_Validation}}"
  65.            Path="MySubClassObj.MyTestBindingRules"
  66.            UpdateSourceTrigger="PropertyChanged"
  67.          >
  68.                     <!--
  69.                UpdateSourceExceptionFilter="{x:Static 
  70.                       local:MyRangeRule.ExceptionFilterCallback}"
  71.                ValidatesOnExceptions ="True"
  72.                      <ExceptionValidationRule/>
  73.              -->
  74.                     <Binding.ValidationRules>
  75.                         <local:MyRangeRule Min="0" Max="1000" />
  76.                     </Binding.ValidationRules>
  77.                 </Binding>
  78.             </TextBox.Text>
  79.         </TextBox>
  80.         <TextBox Style="{StaticResource textBoxInError}"
  81.         HorizontalAlignment="Left"    Grid.Row="1"
  82.         Width="100"  Height="30"
  83.         BorderThickness="2" BorderBrush="SpringGreen"
  84.      >
  85.             <TextBox.Text>
  86.                 <Binding 
  87.              RelativeSource="{
  88.               RelativeSource FindAncestor, 
  89.                AncestorType={x:Type local:UserControl_Data_Validation}}"
  90.              Path="MySubClassObj.MyDate_String"
  91.              UpdateSourceTrigger="PropertyChanged"
  92.              ValidatesOnDataErrors="True"
  93.            />
  94.             </TextBox.Text>
  95.         </TextBox>
  96.         <Button Content="Submit"
  97.            Grid.Row="1"
  98.            Width="100"  Height="30" Click="Button_Click">
  99.             <Button.Style>
  100.                 <Style TargetType="Button">
  101.                     <Setter Property="IsEnabled" Value="False"/>
  102.                     <Style.Triggers>
  103.                         <DataTrigger Value="{x:Static system:String.Empty}" >
  104.                             <Setter Property="IsEnabled" Value="True"/>
  105.                             <DataTrigger.Binding>
  106.                                 <Binding 
  107.                             RelativeSource="{
  108.                             RelativeSource FindAncestor, 
  109.                             AncestorType={x:Type local:UserControl_Data_Validation}}"
  110.                             Path="MySubClassObj.Error"
  111.                             />
  112.                             </DataTrigger.Binding>
  113.                         </DataTrigger>
  114.                     </Style.Triggers>
  115.                 </Style>
  116.             </Button.Style>

  117.         </Button>
  118.         <TextBlock x:Name="MyTextBlock"
  119.              Grid.Column="1" 
  120.              Grid.Row="1" 
  121.              TextWrapping="Wrap" 
  122.              Text="Sumit here" 
  123.              />
  124.     </Grid>
  125. </UserControl>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;

  17. namespace WpfControlLibrary_Hello
  18. {
  19.     /// <summary>
  20.     /// Interaction logic for UserControl_Data_Validation.xaml
  21.     /// </summary>
  22.     public partial class UserControl_Data_Validation : UserControl
  23.     {
  24.         public UserControl_Data_Validation()
  25.         {
  26.             InitializeComponent();
  27.         }
  28.         private void Button_Click(object sender, RoutedEventArgs e)
  29.         {
  30.             MyTextBlock.Text = $"OK {MySubClassObj.MyDate_String}";
  31.         }
  32.     }
  33.     public partial class UserControl_Data_Validation
  34.     {
  35.         static public readonly String NewLine = Environment.NewLine;
  36.         public MySubClass MySubClassObj { get; set; } = new();
  37.         public class MySubClass : IDataErrorInfo, INotifyPropertyChanged
  38.         {
  39.             public event PropertyChangedEventHandler? PropertyChanged;
  40.             public String MyDate_String
  41.             {
  42.                 get => myDate_String;
  43.                 set => myDate_String = value;
  44.             }
  45.             public String this[string columnName]
  46.             {
  47.                 get
  48.                 {
  49.                     String result = String.Empty;
  50.                     if (columnName == nameof(MyDate_String))
  51.                     {
  52.                         if (String.IsNullOrWhiteSpace(myDate_String))
  53.                             result = "Error:IsNullOrWhiteSpace" + Comment;
  54.                         else if (myDate_String.Length > 10) result = " Too long " + Comment;
  55.                         else try
  56.                             {
  57.                                 DateTime _ =
  58.                                 DateTime.ParseExact(myDate_String,
  59.                                   "yyyy/MM/dd",
  60.                                   System.Globalization.CultureInfo.InvariantCulture);
  61.                             }
  62.                             catch (Exception ex)
  63.                             {
  64.                                 result = $"{ex.Message}{NewLine}" + Comment;
  65.                             }
  66.                     }
  67.                     Error = result;
  68.                     return result;
  69.                 }
  70.             }
  71.             private string _Error = "Error";
  72.             public String Error
  73.             {
  74.                 get
  75.                 {
  76.                     return _Error;
  77.                 }
  78.                 set
  79.                 {
  80.                     _Error = value;
  81.                     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Error)));
  82.                 }
  83.             }
  84.             private string myDate_String = "2025/12/3";
  85.             string Comment = $"{NewLine}  Bad format.Using yyyy/MM/dd format";
  86.             int _MyTestBindingRules;
  87.             public int MyTestBindingRules
  88.             {
  89.                 get
  90.                 {
  91.                     return _MyTestBindingRules;
  92.                 }
  93.                 set
  94.                 {
  95.                     _MyTestBindingRules = value;
  96.                 }
  97.             }
  98.         }
  99.     }
  100.     public class MyRangeRule : ValidationRule // TextBox
  101.     {
  102.         static public readonly String NewLine = Environment.NewLine;

  103.         public int Min { get; set; }
  104.         public int Max { get; set; }
  105.         public override ValidationResult Validate(object value, CultureInfo cultureInfo)
  106.         {
  107.             try
  108.             {
  109.                 int TMP = 0;
  110.                 string input = (string)value;
  111.                 if (String.IsNullOrWhiteSpace(input))
  112.                     return new ValidationResult(false,
  113.                         "The input is null or white sapce ");
  114.                 if (input.Length > 0)
  115.                 {
  116.                     TMP = int.Parse(input);
  117.                 }
  118.                 if (TMP > Max || TMP < Min)
  119.                 {
  120.                     return new ValidationResult(false,
  121.                         $"Out of Range{NewLine} Please Enter a number between {Min} and {Max}");
  122.                 }
  123.                 if (TMP == ExceptionNumber)
  124.                 {
  125.                     MessageBoxResult result =
  126.                         MessageBox.Show($"ExceptionNumber= {ExceptionNumber}", "Caprion", MessageBoxButton.YesNo);
  127.                     if (result == MessageBoxResult.Yes)
  128.                         throw new MyException();
  129.                 }
  130.             }
  131.             catch (MyException)
  132.             {
  133.                 throw new MyException("ExceptionNumber");
  134.             }
  135.             catch (Exception ex)
  136.             {
  137.                 return new ValidationResult(false,
  138.                     $"Illegal characters {NewLine} {ex.Message}");
  139.             }
  140.             return new ValidationResult(true, "ValidationResult Ok");
  141.         }
  142.         class MyException : Exception
  143.         {
  144.             public MyException() { }
  145.             public MyException(string str) : base(str) { }
  146.         }
  147.         static int ExceptionNumber = 5; // RandomNumberGenerator.GetInt32(3);
  148.         public static UpdateSourceExceptionFilterCallback ExceptionFilterCallback =
  149.           new UpdateSourceExceptionFilterCallback(Source_ExceptionFilter2);
  150.         static private Object Source_ExceptionFilter2(object bindExpression, Exception exception)
  151.         {
  152.             BindingExpression bindingExpression = (BindingExpression)bindExpression;
  153.             Binding binding = bindingExpression.ParentBinding;
  154.             binding.UpdateSourceExceptionFilter = new
  155.                 UpdateSourceExceptionFilterCallback(Source_ExceptionFilter3);
  156.             MessageBox.Show($"binding.ValidatesOnExceptions= {binding.ValidatesOnExceptions}");
  157.             //bindingExpression.UpdateSource();
  158.             return $"2-->{exception.Message}";
  159.         }
  160.         static private Object Source_ExceptionFilter3(object obj, Exception exception)
  161.         {
  162.             return $"3-->{exception.Message}";
  163.         }
  164.     }
  165. }


  1. <UserControl x:Class="WpfControlLibrary_Hello.UserControl_ListColorNames_class"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.              mc:Ignorable="d" 
  8.              d:DesignHeight="450" d:DesignWidth="800">
  9.     <UserControl.Resources>
  10.         <CollectionViewSource 
  11.        Source="{Binding 
  12.           Source={x:Static local:UserControl_ListColorNames_class.AllItems} 
  13.           }"
  14.          Filter="MyFilter"
  15.           x:Key="MyCollectionViewSource">
  16.             <CollectionViewSource.SortDescriptions>
  17.             </CollectionViewSource.SortDescriptions>
  18.         </CollectionViewSource>
  19.     </UserControl.Resources>
  20.     <Grid>
  21.         <ListBox x:Name="MyListBox1"
  22.          Height="320" Width="300" HorizontalAlignment="Left"
  23.          SelectionChanged="ListBoxSelectionChanged1"
  24.          ItemsSource="{Binding 
  25.                    Source={StaticResource MyCollectionViewSource}}"
  26.          DisplayMemberPath = "Name"
  27.      />
  28.         <ListBox x:Name="MyListBox2"
  29.          Height="320" Width="300" HorizontalAlignment="Right"
  30.          SelectionChanged="ListBoxSelectionChanged2"
  31.          SelectedValuePath="Background"
  32.      />
  33.     </Grid>
  34. </UserControl>

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;

  17. namespace WpfControlLibrary_Hello
  18. {
  19.     /// <summary>
  20.     /// Interaction logic for UserControl_ListColorNames_class.xaml
  21.     /// </summary>
  22.     /// 
  23.     public partial class UserControl_ListColorNames_class : UserControl
  24.     {
  25.         public UserControl_ListColorNames_class()
  26.         {
  27.             InitializeComponent();
  28.             //MyListBox1.ItemsSource = AllItems;
  29.             for (int ii = 0; ii < AllItems.Count; ii++)
  30.             {
  31.                 //MyListBox1.Items.Add(NamedColor.All[ii]);
  32.             }
  33.             //MyListBox1.SelectedValuePath = nameof(NamedColor.Color_Value);
  34.             //MyListBox1.DisplayMemberPath = nameof(NamedColor.Name); 
  35.         }
  36.         void MyFilter(object sender, FilterEventArgs e)
  37.         {
  38.             NamedColor SS = (NamedColor)e.Item;
  39.             if (SS.Name.Length < 26) e.Accepted = true;
  40.             else
  41.             {
  42.                 e.Accepted = false;
  43.             }
  44.         }
  45.         //#pragma warning disable CS0660 // Type defines operator == or operator != but does not override Object.Equals(object o)
  46.         //#pragma warning disable CS0661 // Type defines operator == or operator != but does not override Object.GetHashCode()
  47. #pragma warning disable CS0660, CS0661
  48.         public class MyLabel : System.Windows.Controls.Label
  49. #pragma warning restore CS0661 // Type defines operator == or operator != but does not override Object.GetHashCode()
  50. #pragma warning restore CS0660 // Type defines operator == or operator != but does not override Object.Equals(object o)
  51.         {
  52.             public static bool operator ==(MyLabel left, MyLabel right)
  53.             {
  54.                 return ((String)(left.Content)).CompareTo(((MyLabel)right).Content) == 0;
  55.             }
  56.             public static bool operator !=(MyLabel left, MyLabel right)
  57.             {
  58.                 return !(left == right);
  59.             }
  60.         }
  61.         void ListBoxSelectionChanged1(object sender, SelectionChangedEventArgs e)
  62.         {
  63.             ListBox listBox = (ListBox)sender;
  64.             if (listBox.SelectedIndex >= 0)
  65.             {
  66.                 var GotNamedColor = (NamedColor)listBox.SelectedValue;
  67.                 Background = new SolidColorBrush(GotNamedColor.Color_Value);

  68.                 if (MyListBox2 == null) return;

  69.                 MyLabel label = new()
  70.                 {
  71.                     Background = new SolidColorBrush(GotNamedColor.Color_Value),
  72.                     Content = GotNamedColor.Name2
  73.                 };
  74.                 var myLabels = from MyLabel n in MyListBox2.Items
  75.                                where n == label
  76.                                select n;
  77.                 if (myLabels.Any())
  78.                 {
  79.                     label = myLabels.Single();
  80.                 }
  81.                 else MyListBox2.Items.Add(label);
  82.                 MyListBox2.ScrollIntoView(label);
  83.             }
  84.         }
  85.         void ListBoxSelectionChanged2(object sender, SelectionChangedEventArgs e)
  86.         {
  87.             ListBox listBox = (ListBox)sender;
  88.             if (listBox.SelectedIndex >= 0)
  89.             {
  90.                 //MessageBox.Show(listBox.SelectedValue.GetType().ToString());
  91.                 Background = (SolidColorBrush)listBox.SelectedValue;
  92.             }
  93.         }
  94.         public class MyObservableCollection : ObservableCollection<NamedColor>
  95.         {
  96.         }

  97.         public static MyObservableCollection AllItems
  98.         {
  99.             get => NamedColor.All;
  100.         }
  101.         public class NamedColor
  102.         {
  103.             int ID;
  104.             string Color_PropertyInfo_Name = string.Empty;
  105.             Color _color;
  106.             static MyObservableCollection namedColors;
  107.             static NamedColor()
  108.             {
  109.                 PropertyInfo[] propertyInfo = typeof(Colors).GetProperties();
  110.                 namedColors = new MyObservableCollection();
  111.                 for (int ii = 0; ii < propertyInfo.Length; ii++)
  112.                     namedColors.Add(
  113.                       new NamedColor()
  114.                       {
  115.                           ID = ii,
  116.                           Color_PropertyInfo_Name = propertyInfo[ii].Name,
  117.                           _color = (Color)(propertyInfo[ii].GetValue(null) ??
  118.                                   throw new Exception($"{ii}:_color == null"))
  119.                       }
  120.                     );
  121.             }
  122.             public static MyObservableCollection All
  123.             {
  124.                 get { return namedColors; }
  125.             }
  126.             public Color Color_Value { get { return _color; } }
  127.             public string Name
  128.             {
  129.                 get
  130.                 {
  131.                     StringBuilder strSpaced = new($"{ID,4}:{_color} >> {Color_PropertyInfo_Name[0]}");
  132.                     for (int ii = 1; ii < Color_PropertyInfo_Name.Length; ii++)
  133.                         strSpaced.
  134.                             Append((Char.IsUpper(Color_PropertyInfo_Name[ii]) ? " " : "")).
  135.                             Append(Color_PropertyInfo_Name[ii]);
  136.                     return strSpaced.ToString();
  137.                 }
  138.             }
  139.             public string Name2
  140.             {
  141.                 get => $"{ID,4}:{Color_PropertyInfo_Name}";
  142.             }
  143.             public override string ToString()
  144.             {
  145.                 return Color_PropertyInfo_Name;
  146.             }
  147.         }
  148.     }

  149. }


  1. <UserControl x:Class="WpfControlLibrary_Hello.UserControl_ListColorNames_item"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.              mc:Ignorable="d" 
  8.              d:DesignHeight="450" d:DesignWidth="800">
  9.     <Grid x:Name="MyGrid">
  10.         <ListBox Height="450" Width="320" 
  11.                  x:Name="MyListBox_item"
  12.                  SelectionChanged="ListBoxSelectionChanged_item"
  13.                  SelectedValuePath="Background"
  14.                  SelectedValue="{Binding Path=Background, 
  15.                                  ElementName=MyGrid}"/>
  16.         <!--
  17.             SelectedValue="{Binding Path=Background}" 
  18.             DataContext="{x:Reference Name=MyGrid}"/>
  19.         -->
  20.     </Grid>

  21. </UserControl>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Navigation;
  15. using System.Windows.Shapes;

  16. namespace WpfControlLibrary_Hello
  17. {
  18.     /// <summary>
  19.     /// Interaction logic for UserControl_ListColorNames_item.xaml
  20.     /// </summary>
  21.     public partial class UserControl_ListColorNames_item : UserControl
  22.     {
  23.         public UserControl_ListColorNames_item()
  24.         {
  25.             InitializeComponent();
  26.             MyInitialize();
  27.         }

  28.         void MyInitialize()
  29.         {
  30.             PropertyInfo[] propertyInfo = typeof(Colors).GetProperties();
  31.             for (int ii = 0; ii < propertyInfo.Length; ii++)
  32.             {
  33.                 var item = new ListBoxItem()
  34.                 {
  35.                     Content = Name_item(propertyInfo[ii].Name, ii),
  36.                     Background = new SolidColorBrush((Color)
  37.                         (propertyInfo[ii].GetValue(null) ??
  38.                            throw new Exception($"{ii}:_color == null")
  39.                         )
  40.                     ),
  41.                 };
  42.                 MyListBox_item.Items.Add(item);
  43.             }
  44.             //MyListBox_item.SetBinding(
  45.             //    ListBox.SelectedNumericUpDown_ValueProperty, nameof(Background));
  46.             //MyListBox_item.DataContext = this;
  47.             //MyListBox_item.SelectedValuePath = nameof(ListBoxItem.Background);
  48.         }
  49.         static public string Name_item(string label_Name, int ID)
  50.         {
  51.             StringBuilder strSpaced = new($"{ID,4}:{label_Name[0]}");
  52.             for (int ii = 1; ii < label_Name.Length; ii++)
  53.                 strSpaced.
  54.                           Append((Char.IsUpper(label_Name[ii]) ? " " : "")).
  55.                           Append(label_Name[ii]);
  56.             return strSpaced.ToString();
  57.         }

  58.         void ListBoxSelectionChanged_item(object sender, SelectionChangedEventArgs e)
  59.         {
  60.             ListBox listBox = (ListBox)sender;
  61.             if (listBox.SelectedIndex >= 0)
  62.             {
  63.                 // this.Background = ((ListBoxItem)listBox.SelectedValue).Background;
  64.                 //MessageBox.Show($"{listBox.SelectedIndex}");
  65.             }
  66.             if (e.RemovedItems.Count > 0)
  67.             {
  68.                 var item = (ListBoxItem)(e.RemovedItems[0] ?? throw new Exception());
  69.                 item.FontSize /= 2;
  70.             }
  71.             if (e.AddedItems.Count > 0)
  72.             {
  73.                 var item = (ListBoxItem)(e.AddedItems[0] ?? throw new Exception());
  74.                 item.FontSize *= 2;
  75.             }
  76.         }

  77.     }
  78. }


  1. <UserControl x:Class="WpfControlLibrary_Hello.UserControl_ListColorNames_label"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.              mc:Ignorable="d" 
  8.              d:DesignHeight="450" d:DesignWidth="800">
  9.     <Grid>
  10.         <ListBox Height="400" Width="320" 
  11.                  x:Name="MyListBox"
  12.                  SelectionChanged="ListBoxSelectionChanged_label"
  13.         />
  14.     </Grid>

  15. </UserControl>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Navigation;
  15. using System.Windows.Shapes;

  16. namespace WpfControlLibrary_Hello
  17. {
  18.     /// <summary>
  19.     /// Interaction logic for UserControl_ListColorNames_label.xaml
  20.     /// </summary>
  21.     public partial class UserControl_ListColorNames_label : UserControl
  22.     {
  23.         public UserControl_ListColorNames_label()
  24.         {
  25.             InitializeComponent();
  26.             MyInitialize();
  27.         }
  28.         void MyInitialize()
  29.         {
  30.             PropertyInfo[] propertyInfo = typeof(Colors).GetProperties();
  31.             for (int ii = 0; ii < propertyInfo.Length; ii++)
  32.             {
  33.                 var label = new Label()
  34.                 {
  35.                     Content = Name2(propertyInfo[ii].Name, ii),
  36.                     Background = new SolidColorBrush(
  37.                           (Color)(propertyInfo[ii].GetValue(null) ??
  38.                                     throw new Exception($"{ii}:_color == null")
  39.                          ))
  40.                 };
  41.                 MyListBox.Items.Add(label);
  42.             }
  43.         }
  44.         void ListBoxSelectionChanged_label(object sender, SelectionChangedEventArgs e)
  45.         {
  46.             ListBox listBox = (ListBox)sender;
  47.             if (listBox.SelectedIndex >= 0)
  48.             {
  49.                 this.Background = ((Label)listBox.SelectedValue).Background;
  50.             }
  51.         }
  52.         static public string Name2(string label_Name, int ID)
  53.         {
  54.             StringBuilder strSpaced = new($"{ID,4}:{label_Name[0]}");
  55.             for (int ii = 1; ii < label_Name.Length; ii++)
  56.                 strSpaced.
  57.                           Append((Char.IsUpper(label_Name[ii]) ? " " : "")).
  58.                           Append(label_Name[ii]);
  59.             return strSpaced.ToString();
  60.         }

  61.     }
  62. }


  1. <UserControl x:Class="WpfControlLibrary_Hello.UserControl_ListColorNames_string"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.              mc:Ignorable="d" 
  8.              d:DesignHeight="450" d:DesignWidth="800">
  9.     <UserControl.Resources>
  10.         <local:String_And_BrushConverter  x:Key="String_And_BrushConverterKey"/>
  11.     </UserControl.Resources>

  12.     <Grid>
  13.         <ListBox Height="320" Width="320"
  14.                  ItemsSource="{x:Static 
  15.                    local:UserControl_ListColorNames_string.ColorPropertyNames}"
  16.                  SelectionChanged="ListBoxSelectionChanged"
  17.                  x:Name="ListBox_string" >
  18.             <ListBox.SelectedItem>
  19.                 <Binding Path="Background"
  20.                   Source="{x:Reference MyLabel_1_in_UserControl_ListColorNames_string}"
  21.                   Converter="{StaticResource String_And_BrushConverterKey}"/>
  22.             </ListBox.SelectedItem>
  23.             <!--
  24.              Converter="{x:Static 
  25.                 local:UserControl_ListColorNames_string.MyTestConverter}"/>
  26.             -->
  27.         </ListBox>
  28.         <TextBlock Height="30" Width="100" 
  29.                    HorizontalAlignment="Left" VerticalAlignment="Top"
  30.                    Text="TextBlock_1" 
  31.                    x:Name="TextBlock_1_in_UserControl_ListColorNames_string">
  32.             <TextBlock.Background>
  33.                 <Binding Path="SelectedItem"
  34.                  Source="{x:Reference ListBox_string}"
  35.                  Converter="{StaticResource String_And_BrushConverterKey}"
  36.                  ConverterParameter="AAA"/>
  37.             </TextBlock.Background>
  38.         </TextBlock>
  39.         <TextBlock Height="30" Width="100" 
  40.            HorizontalAlignment="Right" VerticalAlignment="Top"
  41.                    Background="LawnGreen"
  42.            x:Name="TextBlock_2_in_UserControl_ListColorNames_string">
  43.             <TextBlock.Text>
  44.                 <Binding Path="SelectedIndex"
  45.                          Source="{x:Reference ListBox_string}"
  46.                          Converter="{x:Static 
  47.                          local:UserControl_ListColorNames_string.MyGet_String}"
  48.                          ConverterParameter="{x:Reference ListBox_string}"
  49.                 />
  50.             </TextBlock.Text>
  51.         </TextBlock>
  52.         <Label Height="30" Width="100" 
  53.                HorizontalAlignment="Left" VerticalAlignment="Bottom"
  54.                Content="MyLabal_1" Background="Yellow"
  55.                x:Name="MyLabel_1_in_UserControl_ListColorNames_string"
  56.         />
  57.         <Label Height="30" Width="100" 
  58.               HorizontalAlignment="Right" VerticalAlignment="Bottom"
  59.               Content="MyLabal_2" 
  60.               FontWeight="ExtraBold"
  61.               Background="{DynamicResource 
  62.                    {x:Static SystemColors.AccentColorLight3BrushKey}}"
  63.               x:Name="MyLabel_2_in_UserControl_ListColorNames_string"
  64. />
  65.     </Grid>
  66. </UserControl>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. using System.Windows.Controls;
  11. using System.Windows.Data;
  12. using System.Windows.Documents;
  13. using System.Windows.Input;
  14. using System.Windows.Media;
  15. using System.Windows.Media.Imaging;
  16. using System.Windows.Navigation;
  17. using System.Windows.Shapes;

  18. namespace WpfControlLibrary_Hello
  19. {
  20.     /// <summary>
  21.     /// Interaction logic for UserControl_ListColorNames_string.xaml
  22.     /// </summary>
  23.     /// 
  24.     public partial class UserControl_ListColorNames_string : UserControl
  25.     {
  26.         public UserControl_ListColorNames_string()
  27.         {
  28.             InitializeComponent();
  29.             this.Background = new SolidColorBrush(Colors.Red);
  30.             //ListBox_string.SetBinding(
  31.             //     ListBox.SelectedItemProperty, nameof(Background));
  32.             //ListBox_string.DataContext = this;
  33.             //ListBox_string.DataContext = MyLabel_1_in_UserControl_ListColorNames_string;
  34.         }
  35.         private static string[] _ColorPropertyNames = Array.Empty<string>();
  36.         public static string[] ColorPropertyNames
  37.         {
  38.             get
  39.             {
  40.                 if (_ColorPropertyNames != Array.Empty<string>())
  41.                 {
  42.                     return _ColorPropertyNames;
  43.                 }
  44.                 int ii = 0;
  45.                 PropertyInfo[] propertyInfo = typeof(Colors).GetProperties();
  46.                 _ColorPropertyNames = new string[propertyInfo.Length];
  47.                 foreach (PropertyInfo color_propertyInfo in propertyInfo)
  48.                 {
  49.                     _ColorPropertyNames[ii++] = color_propertyInfo.Name;
  50.                 }
  51.                 return _ColorPropertyNames;
  52.             }
  53.         }
  54.         void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
  55.         {
  56.             ListBox listBox = (ListBox)sender;
  57.             if (listBox.SelectedIndex >= 0)
  58.             {
  59.                 var SelectedColor = (String)(listBox.Items[listBox.SelectedIndex]);
  60.                 var color_propertyInfo = typeof(Colors).GetProperty(SelectedColor);
  61.                 if (color_propertyInfo != null)
  62.                 {
  63.                     var color = (Color)
  64.                       (color_propertyInfo.GetValue(null) ?? throw new Exception());
  65.                     MyLabel_2_in_UserControl_ListColorNames_string.Foreground = new SolidColorBrush(color);
  66.                 }
  67.             }


  68.         }
  69.         static public IValueConverter MyTestConverter = new String_And_BrushConverter();
  70.         static public IValueConverter MyGet_String = new Get_String();

  71.     }
  72.     [ValueConversion(typeof(Brush), typeof(string))]
  73.     public class String_And_BrushConverter : IValueConverter
  74.     {
  75.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  76.         {
  77.             BrushConverter brushConverter = new();
  78.             string MyBrush_Str = brushConverter.ConvertToInvariantString(value) ??
  79.                  throw new Exception();
  80.             //MessageBox.Show("Convert :  " + parameter);
  81.             return MyBrush_Str;
  82.         }
  83.         public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  84.         {
  85.             BrushConverter brushConverter = new();
  86.             Brush? MyBrush = (Brush?)brushConverter.ConvertFromString((string)value);
  87.             //MessageBox.Show("ConvertBack : " + parameter);
  88.             return MyBrush is null ?
  89.                      throw new NoNullAllowedException("String_And_BrushConverter")
  90.                    : (object)MyBrush;
  91.         }
  92.     }
  93.     public class Get_String : IValueConverter
  94.     {
  95.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  96.         {
  97.             string MyString = "TextBlock_2";
  98.             var listBox = (ListBox)parameter;
  99.             if (listBox.SelectedIndex >= 0) MyString =
  100.                $"{listBox.SelectedIndex}:{listBox.Items[listBox.SelectedIndex]}";
  101.             return MyString;
  102.         }
  103.         public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  104.         {
  105.             throw new NotImplementedException("Get_String.ConvertBack");
  106.         }
  107.     }
  108. }


  1. <UserControl x:Class="WpfControlLibrary_Hello.UserControl_NumericUpDown"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:WpfControlLibrary_Hello"
  7.              mc:Ignorable="d" 
  8.              d:DesignHeight="450" d:DesignWidth="800">
  9.     <Grid Background="Yellow">
  10.         <Grid.RowDefinitions>
  11.             <RowDefinition/>
  12.             <RowDefinition/>
  13.         </Grid.RowDefinitions>
  14.         <Grid.ColumnDefinitions>
  15.             <ColumnDefinition/>
  16.             <ColumnDefinition/>
  17.             <ColumnDefinition/>
  18.         </Grid.ColumnDefinitions>
  19.         <TextBlock Width="150" Height="30" Background="Red"
  20.                        TextAlignment="Center">
  21.             <TextBlock.Text>
  22.                 <Binding 
  23.                    RelativeSource="{RelativeSource FindAncestor, 
  24.                          AncestorType={x:Type local:UserControl_NumericUpDown}}"
  25.                    Path="NumericUpDown_Value">
  26.                 </Binding>
  27.             </TextBlock.Text>
  28.         </TextBlock>
  29.         <Button Width="130" Height="20" Grid.Row="1"
  30.                   Content="Trace" Click="Button_Click" />
  31.         <RepeatButton Name="upButton" Click="upButton_Click" 
  32.                   Background="Green"   Width="100" Height="20"
  33.                   Grid.Column="1" Grid.Row="0">Up</RepeatButton>
  34.         <RepeatButton Name="downButton" Click="downButton_Click" 
  35.                   Background="Lime"  Width="100" Height="20"
  36.                   Grid.Column="1" Grid.Row="1">Down</RepeatButton>
  37.         <TextBlock x:Name="MyTrace" Grid.Column="2" Grid.RowSpan="2"/>
  38.     </Grid>

  39. </UserControl>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Navigation;
  15. using System.Windows.Shapes;

  16. namespace WpfControlLibrary_Hello
  17. {
  18.     /// <summary>
  19.     /// Interaction logic for UserControl_NumericUpDown.xaml
  20.     /// </summary>
  21.     /// 
  22.     public partial class UserControl_NumericUpDown : UserControl
  23.     {
  24.         public UserControl_NumericUpDown()
  25.         {
  26.             InitializeComponent();
  27.         }
  28.         /// Identifies the NumericUpDown_Value dependency property.
  29.         public static readonly DependencyProperty NumericUpDown_ValueProperty =
  30.             DependencyProperty.Register(
  31.              nameof(NumericUpDown_Value), typeof(decimal), typeof(UserControl_NumericUpDown),
  32.              new FrameworkPropertyMetadata(2m,
  33.              new PropertyChangedCallback(OnValueChanged),
  34.              new CoerceValueCallback(CoerceValue)));
  35.         //new CoerceValueCallback(CoerceValue)));
  36.         /// Identifies the ValueChanged routed event.
  37.         public static readonly RoutedEvent ValueChangedEvent =
  38.             EventManager.RegisterRoutedEvent(
  39.             nameof(ValueChanged), RoutingStrategy.Bubble,
  40.             typeof(RoutedPropertyChangedEventHandler<decimal>),
  41.             typeof(UserControl_NumericUpDown));

  42.         /// Gets or sets the value assigned to the control.
  43.         public decimal NumericUpDown_Value
  44.         {
  45.             get { trace("get NumericUpDown_Value"); return (decimal)GetValue(NumericUpDown_ValueProperty); }
  46.             set { trace("set NumericUpDown_Value"); SetValue(NumericUpDown_ValueProperty, value); }
  47.         }
  48.         public const decimal MinValue = 0;
  49.         public const decimal MaxValue = 10;

  50.         private static object CoerceValue(DependencyObject element, object value)
  51.         {
  52.             trace("CoerceValue");
  53.             var control = (UserControl_NumericUpDown)element;
  54.             decimal newValue = (decimal)value;
  55.             newValue = Math.Max(MinValue, Math.Min(MaxValue, newValue));
  56.             return newValue;
  57.         }
  58.         private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
  59.         {
  60.             trace("OnValueChanged");
  61.             var control = (UserControl_NumericUpDown)obj;
  62.             var e = new RoutedPropertyChangedEventArgs<decimal>(
  63.                      (decimal)args.OldValue, (decimal)args.NewValue, ValueChangedEvent);
  64.             control.OnValueChanged(e);
  65.         }
  66.         /// Occurs when the NumericUpDown_Value property changes.
  67.         public event RoutedPropertyChangedEventHandler<decimal> ValueChanged
  68.         {
  69.             add { trace("add AddHandler"); AddHandler(ValueChangedEvent, value); }
  70.             remove { trace("remove AddHandler"); RemoveHandler(ValueChangedEvent, value); }
  71.         }
  72.         /// Raises the ValueChanged event.
  73.         /// <param name="args">Arguments associated with the ValueChanged event.</param>
  74.         protected virtual void OnValueChanged(RoutedPropertyChangedEventArgs<decimal> args)
  75.         {
  76.             trace("RaiseEvent");
  77.             RaiseEvent(args);
  78.         }
  79.         private void upButton_Click(object sender, EventArgs e)
  80.         {
  81.             trace("*********** upButton_Click ***********");
  82.             NumericUpDown_Value++;
  83.             trace("*********** upButton_Click ***********");
  84.         }
  85.         private void downButton_Click(object sender, EventArgs e)
  86.         {
  87.             trace("******* downButton_Click *********");
  88.             NumericUpDown_Value--;
  89.             trace("******* downButton_Click *********");
  90.         }
  91.         private void Button_Click(object sender, RoutedEventArgs e)
  92.         {
  93.             MyTrace.Text = _Tracer.ToString(); _Tracer.Clear();
  94.         }
  95.         static StringBuilder _Tracer = new StringBuilder();
  96.         public static void trace(string message) { _Tracer.AppendLine(message); }
  97.     }
  98. }










留言

這個網誌中的熱門文章

Marshalling

Marshalling II