WPF XAML demo: Difference between revisions
Jump to navigation
Jump to search
(This is an essay, not an article, so it shouldn't use article subject styling) |
m (Text replacement - "<source" to "<syntaxhighlight") |
||
Line 11: | Line 11: | ||
{{Collapse|Here is an example of XAML found in the attached namespace called '''sample1''':| | {{Collapse|Here is an example of XAML found in the attached namespace called '''sample1''':| | ||
< | <syntaxhighlight lang=xml> | ||
<Window | <Window | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
Line 47: | Line 47: | ||
=== FixSimpleXaml === | === FixSimpleXaml === | ||
If you install the attached namespace and execute the following 2 lines in your workspace: | If you install the attached namespace and execute the following 2 lines in your workspace: | ||
< | <syntaxhighlight lang=apl> | ||
win ← FixSimpleXaml sample1 | win ← FixSimpleXaml sample1 | ||
win.Show | win.Show | ||
Line 55: | Line 55: | ||
{{attachment:Sample1.png || width=250}} | {{attachment:Sample1.png || width=250}} | ||
< | <syntaxhighlight lang=apl inline>FixSimpleXaml</source> is a function used to execute the XAML and return the root element as a .Net object. All the other elements that are named in the XAML will be attached to their names to the root object automatically. | ||
For example, the element '''!TextBox''' that is named '''textBox1''' (line 15) and the element '''Button''' that is named '''button1''' (line 22) are attached automatically to the root element by the function < | For example, the element '''!TextBox''' that is named '''textBox1''' (line 15) and the element '''Button''' that is named '''button1''' (line 22) are attached automatically to the root element by the function <syntaxhighlight lang=apl inline>FixSimpleXaml</source>: | ||
< | <syntaxhighlight lang=apl> | ||
win.textBox1.Text | win.textBox1.Text | ||
Textbox | Textbox | ||
Line 65: | Line 65: | ||
</source> | </source> | ||
That way you don't need to define a separate variable for each named element. If you install the [[user command]] called < | That way you don't need to define a separate variable for each named element. If you install the [[user command]] called <syntaxhighlight lang=apl inline>sfPropGrid</source> you can see all the properties, methods and events of all the named objects by doing (click the combo of NOE to access all the named objects): | ||
< | <syntaxhighlight lang=apl> | ||
]noe win ⍝ noe = .Net Object Explorer | ]noe win ⍝ noe = .Net Object Explorer | ||
</source> | </source> | ||
In conclusion < | In conclusion <syntaxhighlight lang=apl inline>FixSimpleXaml</source> is a simple function to use on simple XAML that does not have events and is properly formed. In production code you may want to do something like this: | ||
< | <syntaxhighlight lang=apl> | ||
:If ⎕NULL≡myObject ← FixSimpleXaml myXaml | :If ⎕NULL≡myObject ← FixSimpleXaml myXaml | ||
⍝ Fixing the XAML did not work. Show an error and exit. | ⍝ Fixing the XAML did not work. Show an error and exit. | ||
Line 81: | Line 81: | ||
=== FixXaml === | === FixXaml === | ||
{{Collapse|For cases where there are events that need to be fixed and have better error handling the function < | {{Collapse|For cases where there are events that need to be fixed and have better error handling the function <syntaxhighlight lang=apl inline>FixXaml</source> is available. It is useful when using XAML taken directly from Visual Studio. For example, with the XAML code in '''sample2''' that has an event on the button (Click<nowiki>=</nowiki>"<syntaxhighlight lang=apl inline>__Button_Click</source>") at line 24, if you do the following:| | ||
< | <syntaxhighlight lang=xml> | ||
<Window | <Window | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
Line 117: | Line 117: | ||
</source> | </source> | ||
}} | }} | ||
< | <syntaxhighlight lang=apl> | ||
win ← FixXaml sample2 | win ← FixXaml sample2 | ||
win.Show | win.Show | ||
Line 123: | Line 123: | ||
</source> | </source> | ||
and then if you click on the button, the value of the '''!TextBox''' will change. The value of the '''!TextBox''' can be retrieved simply by doing: | and then if you click on the button, the value of the '''!TextBox''' will change. The value of the '''!TextBox''' can be retrieved simply by doing: | ||
< | <syntaxhighlight lang=apl> | ||
win.textBox1.Text | win.textBox1.Text | ||
I Was Clicked ! | I Was Clicked ! | ||
</source> | </source> | ||
The function < | The function <syntaxhighlight lang=apl inline>__Button_Click</source> is handling the event. The author has taken the convention of naming the callback functions with a double underscore prefix. | ||
The goal is to be able to take the XAML directly from Visual Studio to APL. The single underscore '_' is a valid first character in Visual Studio and APL but is in conflict with the menu object that will accept an underscore as the first character to define a keyboard shortcut. | The goal is to be able to take the XAML directly from Visual Studio to APL. The single underscore '_' is a valid first character in Visual Studio and APL but is in conflict with the menu object that will accept an underscore as the first character to define a keyboard shortcut. | ||
The line 5 of '''sample2''' (x:Class="!WpfApplication3.!MainWindow") that is required by Visual Studio is removed by < | The line 5 of '''sample2''' (x:Class="!WpfApplication3.!MainWindow") that is required by Visual Studio is removed by <syntaxhighlight lang=apl inline>FixXaml</source>. See the comments in the function for more information. | ||
In production code you may want to trap any error by using code like this: | In production code you may want to trap any error by using code like this: | ||
< | <syntaxhighlight lang=apl> | ||
:If ⎕NULL≡↑myObject ← FixXaml myXaml | :If ⎕NULL≡↑myObject ← FixXaml myXaml | ||
⍝ Fixing the XAML did not work. Show an error and exit. | ⍝ Fixing the XAML did not work. Show an error and exit. | ||
Line 146: | Line 146: | ||
=== About ⎕USING === | === About ⎕USING === | ||
In general, when using XAML there is no need to define a < | In general, when using XAML there is no need to define a <syntaxhighlight lang=apl inline>⎕USING</source> before fixing it except when there is a 3rd party dll involved. For example, the variable <syntaxhighlight lang=apl inline>NewWindow</source> is defined as: | ||
< | <syntaxhighlight lang=apl> | ||
<Window | <Window | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
Line 154: | Line 154: | ||
</source> | </source> | ||
and if you do: | and if you do: | ||
< | <syntaxhighlight lang=apl> | ||
win ← FixSimpleXaml NewWindow | win ← FixSimpleXaml NewWindow | ||
win.Show | win.Show | ||
</source> | </source> | ||
a Window will appear. In procedural code, the following is required for the same result: | a Window will appear. In procedural code, the following is required for the same result: | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING←'System.Windows,WPF/PresentationFramework.dll' | ⎕USING←'System.Windows,WPF/PresentationFramework.dll' | ||
win ← ⎕NEW Window | win ← ⎕NEW Window | ||
win.Show | win.Show | ||
</source> | </source> | ||
The first element of XAML must contain the '''xmlns=''' and the '''xmlns:x=''' declarations. This is instructing the parser (in our case '''System.Windows.Markup.!XamlReader''' in the function < | The first element of XAML must contain the '''xmlns=''' and the '''xmlns:x=''' declarations. This is instructing the parser (in our case '''System.Windows.Markup.!XamlReader''' in the function <syntaxhighlight lang=apl inline>FixSimpleXaml</source> and <syntaxhighlight lang=apl inline>FixXaml</source>) to load a series of .NET namespaces required to parse the XAML. This is just a convention, there is actually no such web site. | ||
=== 3rd Party Dll === | === 3rd Party Dll === | ||
When using 3rd party dll, they must be added to the declaration in the first element of XAML. There are 2 choices on how to do it: | When using 3rd party dll, they must be added to the declaration in the first element of XAML. There are 2 choices on how to do it: | ||
< | <syntaxhighlight lang=apl> | ||
xmlns:myname="clr‑namespace:MyNamespace;assembly=MyDllName" ⍝ Notice that there is no '.dll' after MyDllName | xmlns:myname="clr‑namespace:MyNamespace;assembly=MyDllName" ⍝ Notice that there is no '.dll' after MyDllName | ||
or | or | ||
Line 175: | Line 175: | ||
</source> | </source> | ||
The method on the first line is recommended. Here is an example with the Syncfusion !PropertyGrid: | The method on the first line is recommended. Here is an example with the Syncfusion !PropertyGrid: | ||
< | <syntaxhighlight lang=apl> | ||
xmlns:sf="clr-namespace:Syncfusion.Windows.PropertyGrid;assembly=Syncfusion.PropertyGrid.Wpf" ⍝ Notice no .dll at the end | xmlns:sf="clr-namespace:Syncfusion.Windows.PropertyGrid;assembly=Syncfusion.PropertyGrid.Wpf" ⍝ Notice no .dll at the end | ||
</source> | </source> | ||
and the XAML will look like this: | and the XAML will look like this: | ||
< | <syntaxhighlight lang=apl> | ||
<sf:PropertyGrid x:Name="PGrid"/> ⍝ Notice the prefix 'sf' is the same on both lines (you choose the prefix). | <sf:PropertyGrid x:Name="PGrid"/> ⍝ Notice the prefix 'sf' is the same on both lines (you choose the prefix). | ||
</source> | </source> | ||
but this is not enough, < | but this is not enough, <syntaxhighlight lang=apl inline>⎕USING</source> must be set up correctly before fixing the XAML for 3rd party dlls in order for the parser to find the assembly. Here is an example for the Syncfusion !PropertyGrid ('''Syncfusion/4.5/''' is the Dyalog sub-directory where the assemblies live): | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING ← 'Syncfusion.Windows.PropertyGrid,Syncfusion/4.5/Syncfusion.PropertyGrid.Wpf.dll' ⍝ The .dll is required | ⎕USING ← 'Syncfusion.Windows.PropertyGrid,Syncfusion/4.5/Syncfusion.PropertyGrid.Wpf.dll' ⍝ The .dll is required | ||
Line 192: | Line 192: | ||
⎕USING ← 'MyNamespace,MyDllName.dll' ⍝ If the dll is in the same directory as dyalog.exe | ⎕USING ← 'MyNamespace,MyDllName.dll' ⍝ If the dll is in the same directory as dyalog.exe | ||
</source> | </source> | ||
Another thing with the value of < | Another thing with the value of <syntaxhighlight lang=apl inline>⎕USING</source> for 3rd party dll is that it must be set in the __same namespace__ as where <syntaxhighlight lang=apl inline>FixXaml</source> or <syntaxhighlight lang=apl inline>FixSimpleXaml</source> is located (because <syntaxhighlight lang=apl inline>⎕USING</source> is Namespace scope). Alternatively, if you setup your <syntaxhighlight lang=apl inline>dyalog.exe.config</source> file that is in the same directory as the <syntaxhighlight lang=apl inline>dyalog.exe</source> file with a directive to look in the <syntaxhighlight lang=apl inline>Syncfusion/4.5</source> directory you will not need to set up <syntaxhighlight lang=apl inline>⎕USING</source> and you don't need to worry about loading it into memory. | ||
Typically the file will look like this: | Typically the file will look like this: | ||
< | <syntaxhighlight lang=apl> | ||
<configuration> | <configuration> | ||
<startup useLegacyV2RuntimeActivationPolicy="true"> | <startup useLegacyV2RuntimeActivationPolicy="true"> | ||
Line 212: | Line 212: | ||
</source> | </source> | ||
When using procedural code instead of XAML you may want to define a one time < | When using procedural code instead of XAML you may want to define a one time <syntaxhighlight lang=apl inline>⎕USING</source> like this: | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING←Using | ⎕USING←Using | ||
</source> | </source> | ||
{{Collapse|A typical definition of the function < | {{Collapse|A typical definition of the function <syntaxhighlight lang=apl inline>Using</source> is like this (contributed by Dyalog and Michael J. Hughes):| | ||
< | <syntaxhighlight lang=apl> | ||
use←Using | use←Using | ||
⍝ Full ⎕Using used by system. | ⍝ Full ⎕Using used by system. | ||
Line 257: | Line 257: | ||
</source> | </source> | ||
}} | }} | ||
To add a new definition to an existing < | To add a new definition to an existing <syntaxhighlight lang=apl inline>⎕USING</source> and to prevent duplicate entries the 'Union' operator is used like this: | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING∪←⊂'System.Windows.Controls,PresentationFramework.dll' | ⎕USING∪←⊂'System.Windows.Controls,PresentationFramework.dll' | ||
</source> | </source> | ||
=== Fixing Images === | === Fixing Images === | ||
In XAML you declare an Image object that is on disk the following way: | In XAML you declare an Image object that is on disk the following way: | ||
< | <syntaxhighlight lang=apl> | ||
<Image x:Name="MyImageName" | <Image x:Name="MyImageName" | ||
Source="PathOfMyImage\MyImage.png" ⍝ PathOfMyImage can be tricky to declare sometimes and is not discussed here. | Source="PathOfMyImage\MyImage.png" ⍝ PathOfMyImage can be tricky to declare sometimes and is not discussed here. | ||
Line 277: | Line 277: | ||
==== Step 1: Save all the images in the workspace with the function FileToBase64String ==== | ==== Step 1: Save all the images in the workspace with the function FileToBase64String ==== | ||
At design time, save the images in the workspace. The APL variable name of any image must be the original name of the image name in the XAML with the added suffix '''_b64''' (naming convention only). | At design time, save the images in the workspace. The APL variable name of any image must be the original name of the image name in the XAML with the added suffix '''_b64''' (naming convention only). | ||
< | <syntaxhighlight lang=apl> | ||
Paste_b64 ← FileToBase64String 'D:\Paste.png' | Paste_b64 ← FileToBase64String 'D:\Paste.png' | ||
Copy_b64 ← FileToBase64String 'D:\Copy.png' | Copy_b64 ← FileToBase64String 'D:\Copy.png' | ||
Cut_b64 ← FileToBase64String 'D:\Cut.png' | Cut_b64 ← FileToBase64String 'D:\Cut.png' | ||
</source> | </source> | ||
The variable < | The variable <syntaxhighlight lang=apl inline>Copy_b64</source> in the attached namespace looks like this: | ||
< | <syntaxhighlight lang=apl> | ||
Copy_b64 | Copy_b64 | ||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAaVBMVEX///8AAAC2tra2tra2tra2trb////+/v62trb9/f309PT7+/vExMSurq6Hh4f4+Pj8/Pz5+fnMzMyenp6/zduoqKilpaXNzc2xsbHu7u6Li4vk5OTa2tro6Oj6+vrm5uaMjIympqby8vJPA9lJAAAABnRSTlMAAM8Q7zCjkYU+AAAAiklEQVR4XoXM2Q7CMAxE0bqAk+7s+/7/H4mJMGNXQdzXo5mCiKK2X01nlCpSkbXdspxk4VCLOHBvDvwbYPSWgxu/JQMn5rotMzA8L+d24wAFB+tvzEeFIGDr/0LlrjwEE2D+CxoZ4aoCLASQgau8mQAsb7hqFLp7L28mBSKKPJgS0AdcgO6xtQm8AN3LEZUq6MiXAAAAAElFTkSuQmCC | iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAaVBMVEX///8AAAC2tra2tra2tra2trb////+/v62trb9/f309PT7+/vExMSurq6Hh4f4+Pj8/Pz5+fnMzMyenp6/zduoqKilpaXNzc2xsbHu7u6Li4vk5OTa2tro6Oj6+vrm5uaMjIympqby8vJPA9lJAAAABnRSTlMAAM8Q7zCjkYU+AAAAiklEQVR4XoXM2Q7CMAxE0bqAk+7s+/7/H4mJMGNXQdzXo5mCiKK2X01nlCpSkbXdspxk4VCLOHBvDvwbYPSWgxu/JQMn5rotMzA8L+d24wAFB+tvzEeFIGDr/0LlrjwEE2D+CxoZ4aoCLASQgau8mQAsb7hqFLp7L28mBSKKPJgS0AdcgO6xtQm8AN3LEZUq6MiXAAAAAElFTkSuQmCC | ||
Line 290: | Line 290: | ||
This format is perfect for scripted namespaces; compare this to storing the image with the original file values that would have some non-visual characters. | This format is perfect for scripted namespaces; compare this to storing the image with the original file values that would have some non-visual characters. | ||
==== Step 2: Set the .Source of each Image with the function ImageFromBase64String ==== | ==== Step 2: Set the .Source of each Image with the function ImageFromBase64String ==== | ||
At run time, after obtaining the root object set the < | At run time, after obtaining the root object set the <syntaxhighlight lang=apl inline>.Source</source> of each Image from the previously saved APL variable. | ||
< | <syntaxhighlight lang=apl> | ||
win ← FixSimpleXaml sample3 | win ← FixSimpleXaml sample3 | ||
Line 299: | Line 299: | ||
</source> | </source> | ||
If there are many images in the XAML, the following lines of code can automate the process at run time: | If there are many images in the XAML, the following lines of code can automate the process at run time: | ||
< | <syntaxhighlight lang=apl> | ||
⍝ Get the names of all the 'Image' object that has been fixed in the root object | ⍝ Get the names of all the 'Image' object that has been fixed in the root object | ||
imgNames ← {((⊂'Image')≡¨(⍵.⍎¨(⍵.⎕NL-9)).GetType.Name)/(⍵.⎕NL-9)} win | imgNames ← {((⊂'Image')≡¨(⍵.⍎¨(⍵.⎕NL-9)).GetType.Name)/(⍵.⎕NL-9)} win | ||
Line 308: | Line 308: | ||
</source> | </source> | ||
The icon and the cursor of the main window can be fixed manually by doing the following: | The icon and the cursor of the main window can be fixed manually by doing the following: | ||
< | <syntaxhighlight lang=apl> | ||
⍝ Fix manually the Icon of the main window. | ⍝ Fix manually the Icon of the main window. | ||
win.Icon ← ImageFromBase64String Settings_b64 | win.Icon ← ImageFromBase64String Settings_b64 | ||
Line 317: | Line 317: | ||
=== Routed Events === | === Routed Events === | ||
In WPF it is possible to set a single function that will receive all the Click events on the window (in this example it is < | In WPF it is possible to set a single function that will receive all the Click events on the window (in this example it is <syntaxhighlight lang=apl inline>__EventHandler</source>) by doing: | ||
< | <syntaxhighlight lang=apl> | ||
⍝ Set Routed Events on the whole Window for ClickEvent when a MenuItem or a Button are clicked. | ⍝ Set Routed Events on the whole Window for ClickEvent when a MenuItem or a Button are clicked. | ||
⎕USING←'System.Windows,WPF/PresentationCore.dll' 'System.Windows.Controls.Primitives,WPF/PresentationFramework.dll' | ⎕USING←'System.Windows,WPF/PresentationCore.dll' 'System.Windows.Controls.Primitives,WPF/PresentationFramework.dll' | ||
Line 325: | Line 325: | ||
</source> | </source> | ||
This is useful because that way you don't need to define individual click events for each control. | This is useful because that way you don't need to define individual click events for each control. | ||
{{Collapse|The function < | {{Collapse|The function <syntaxhighlight lang=apl inline>__EventHandler</source> will handle all the click events on the window code (the double underscore prefix is not necessary but is kept for naming consistency)| | ||
< | <syntaxhighlight lang=apl> | ||
__EventHandler(sender event);name | __EventHandler(sender event);name | ||
⍝ Single Event Handler for the Window | ⍝ Single Event Handler for the Window | ||
Line 364: | Line 364: | ||
When all this is done the window can be shown: | When all this is done the window can be shown: | ||
< | <syntaxhighlight lang=apl> | ||
win.Show | win.Show | ||
</source> | </source> | ||
{{Collapse|The function < | {{Collapse|The function <syntaxhighlight lang=apl inline>DemoSample3</source> contains all the code related to '''sample3'''| | ||
< | <syntaxhighlight lang=apl> | ||
∇ DemoSample3;imgNames | ∇ DemoSample3;imgNames | ||
Line 397: | Line 397: | ||
}} | }} | ||
{{Collapse|The function < | {{Collapse|The function <syntaxhighlight lang=apl inline>ScrubAndFix</source> will remove all the events from the XAML by looping on a <syntaxhighlight lang=apl inline>XamlXmlReader</source> object. It is slower than <syntaxhighlight lang=apl inline>FixXaml</source> but the events don't need to have a specific prefix. Perfect for experimenting with the XAML taken directly from the Web. All the named objects are attached to the root object| | ||
< | <syntaxhighlight lang=apl> | ||
∇ rootObj←ScrubAndFix xamlString;err;names;nodeNumber;reader;stringReader;writer;⎕USING | ∇ rootObj←ScrubAndFix xamlString;err;names;nodeNumber;reader;stringReader;writer;⎕USING | ||
⍝ Function to remove the Class and Events elements of XAML and fix the resulting XAML. | ⍝ Function to remove the Class and Events elements of XAML and fix the resulting XAML. | ||
Line 500: | Line 500: | ||
=== Inserting WPF Controls into Traditional Dyalog Windows === | === Inserting WPF Controls into Traditional Dyalog Windows === | ||
You can insert a WPF control into an already existing application developed with < | You can insert a WPF control into an already existing application developed with <syntaxhighlight lang=apl inline>⎕WC</source> by using an [https://msdn.microsoft.com/en-us/library/system.windows.forms.integration.elementhost(v=vs.110).aspx ElementHost] and a Dyalog's <syntaxhighlight lang=apl inline>NetControl</source>. Here is an example of how to insert a WPF Button: | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING∪←⊂'System.Windows.Forms.Integration,WPF/WindowsFormsIntegration.dll' ⍝ Location of 'ElementHost' | ⎕USING∪←⊂'System.Windows.Forms.Integration,WPF/WindowsFormsIntegration.dll' ⍝ Location of 'ElementHost' | ||
⎕USING∪←⊂'System.Windows.Controls,WPF/PresentationFramework.dll' ⍝ Location of WPF Button | ⎕USING∪←⊂'System.Windows.Controls,WPF/PresentationFramework.dll' ⍝ Location of WPF Button | ||
Line 514: | Line 514: | ||
F.eh.Child ← bn | F.eh.Child ← bn | ||
</source> | </source> | ||
Instead of a Button, you could use some complex XAML developed with Visual Studio. You just need to fix the XAML with < | Instead of a Button, you could use some complex XAML developed with Visual Studio. You just need to fix the XAML with <syntaxhighlight lang=apl inline>FixXaml</source> and make it the child of the <syntaxhighlight lang=apl inline>ElementHost</source> element. | ||
=== How to Access the UI Thread from Another Thread === | === How to Access the UI Thread from Another Thread === | ||
Since Net 2.0 Microsoft does not allow writing on the UI thread from another thread for security and stability reasons. Consequently, if you are executing a long calculation on another thread and you want to show the results by accessing directly the UI thread it is not possible. | Since Net 2.0 Microsoft does not allow writing on the UI thread from another thread for security and stability reasons. Consequently, if you are executing a long calculation on another thread and you want to show the results by accessing directly the UI thread it is not possible. | ||
==== With a Delegate ==== | ==== With a Delegate ==== | ||
{{Collapse|You need to use a little function with the code to be executed that will be put in queue to be executed on the UI thread. This is called a 'Delegate' by Microsoft. The function < | {{Collapse|You need to use a little function with the code to be executed that will be put in queue to be executed on the UI thread. This is called a 'Delegate' by Microsoft. The function <syntaxhighlight lang=apl inline>DispatchDelegate</source> is an example of how to do this| | ||
< | <syntaxhighlight lang=apl> | ||
obj DispatchDelegate action;delegate;⎕USING | obj DispatchDelegate action;delegate;⎕USING | ||
⍝ Function to write asynchronously to the UI thread from another thread. | ⍝ Function to write asynchronously to the UI thread from another thread. | ||
Line 553: | Line 553: | ||
}} | }} | ||
Here is an example of how to use that function: | Here is an example of how to use that function: | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING←'System.Windows,WPF/PresentationFramework.dll' | ⎕USING←'System.Windows,WPF/PresentationFramework.dll' | ||
win ← ⎕NEW Window | win ← ⎕NEW Window | ||
Line 561: | Line 561: | ||
win DispatchDelegate& 'win.Title←''MyDelegateTitle''' ⍝ The .Title property is changed from another thread | win DispatchDelegate& 'win.Title←''MyDelegateTitle''' ⍝ The .Title property is changed from another thread | ||
</source> | </source> | ||
{{Collapse|If you have many lines that need to be executed in the UI thread the function < | {{Collapse|If you have many lines that need to be executed in the UI thread the function <syntaxhighlight lang=apl inline>ScriptFollowsDispatchDelegate</source> can be used like this| | ||
< | <syntaxhighlight lang=apl> | ||
ScriptFollowsDispatchDelegate obj;actions;delegate;dtlb;⎕IO;⎕ML;⎕USING | ScriptFollowsDispatchDelegate obj;actions;delegate;dtlb;⎕IO;⎕ML;⎕USING | ||
⍝ Function to write asynchronously to the UI thread from another thread. | ⍝ Function to write asynchronously to the UI thread from another thread. | ||
Line 601: | Line 601: | ||
</source> | </source> | ||
}} | }} | ||
< | <syntaxhighlight lang=apl> | ||
[3] | [3] | ||
[4] ⍝ ... long running process on another thread ... | [4] ⍝ ... long running process on another thread ... | ||
Line 614: | Line 614: | ||
==== With a DispatcherTimer ==== | ==== With a DispatcherTimer ==== | ||
If you have a repetitive task to be executed on the UI thread then you can use a [https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=vs.110).aspx DispatcherTimer] like this: | If you have a repetitive task to be executed on the UI thread then you can use a [https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=vs.110).aspx DispatcherTimer] like this: | ||
< | <syntaxhighlight lang=apl> | ||
⎕USING∪←'System.Windows,WPF/WindowsBase.dll' 'System,mscorlib.dll' | ⎕USING∪←'System.Windows,WPF/WindowsBase.dll' 'System,mscorlib.dll' | ||
tm1_obj ← ⎕NEW Threading.DispatcherTimer(Threading.DispatcherPriority.Normal myObj.Dispatcher) | tm1_obj ← ⎕NEW Threading.DispatcherTimer(Threading.DispatcherPriority.Normal myObj.Dispatcher) | ||
Line 621: | Line 621: | ||
tm1_obj.Start | tm1_obj.Start | ||
</source> | </source> | ||
Note that since the < | Note that since the <syntaxhighlight lang=apl inline>DispatcherTimer</source> is executed on the UI thread you cannot have a long callback because it will freeze the UI during its execution. | ||
==== With a BackgroundWorker ==== | ==== With a BackgroundWorker ==== | ||
The .NET framework provides a simple way to get started in threading with the [https://msdn.microsoft.com/fr-fr/library/cc221403(v=vs.95).aspx BackgroundWorker] component. This wraps much of the complexity and makes spawning a background thread relatively safe. It offers several features which include spawning a background thread, the ability to cancel the background process before it has completed, and the chance to report the progress back to your UI. The < | The .NET framework provides a simple way to get started in threading with the [https://msdn.microsoft.com/fr-fr/library/cc221403(v=vs.95).aspx BackgroundWorker] component. This wraps much of the complexity and makes spawning a background thread relatively safe. It offers several features which include spawning a background thread, the ability to cancel the background process before it has completed, and the chance to report the progress back to your UI. The <syntaxhighlight lang=apl inline>BackgroundWorker</source> is an excellent tool when you want multithreading in your application with access to the UI thread, mainly because it's so easy to use. | ||
An example is included in this namespace. It is inspired by [http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/ this article]. You start the example by doing: | An example is included in this namespace. It is inspired by [http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/ this article]. You start the example by doing: | ||
< | <syntaxhighlight lang=apl> | ||
BackgroundWorkerSample& 1000 | BackgroundWorkerSample& 1000 | ||
</source> | </source> | ||
Line 635: | Line 635: | ||
# Download [[attachment:wpfXamlDemo.v1.6.txt]] | # Download [[attachment:wpfXamlDemo.v1.6.txt]] | ||
# Do a Select all (Ctrl+A) and a copy (Ctrl+C). | # Do a Select all (Ctrl+A) and a copy (Ctrl+C). | ||
# In your workspace execute < | # In your workspace execute <syntaxhighlight lang=apl inline>)ed ⍟ wpfXamlDemo </source> | ||
# Paste (Ctrl+V) the text into the Dyalog editor | # Paste (Ctrl+V) the text into the Dyalog editor | ||
# Press Escape and ')save' your workspace | # Press Escape and ')save' your workspace | ||
Optionally to de-script the namespace you can do: | Optionally to de-script the namespace you can do: | ||
< | <syntaxhighlight lang=apl> | ||
#.wpfXamlDemo←{('n' ⎕NS ⍵)⊢n←⎕NS ''}#.wpfXamlDemo | #.wpfXamlDemo←{('n' ⎕NS ⍵)⊢n←⎕NS ''}#.wpfXamlDemo | ||
</source> | </source> | ||
[[Category:Tutorials]][[Category:Dyalog APL examples]][[Category:.NET]] | [[Category:Tutorials]][[Category:Dyalog APL examples]][[Category:.NET]] |