HelixViewport3d Ctrl + C - c#

I am using HelixToolkit.Wpf in a WPF / .Net Framework 4.7.2 application. I am trying to make a copy-paste functionality. To achive it, I have the following code in my xaml file:
<KeyBinding Key="C" Modifiers="Control" Command="{Binding CopyCommand}" />
<KeyBinding Key="V" Modifiers="Control" Command="{Binding PasteCommand}" />
The PasteCommand is called as expected, but the CopyCommand is not.
When profiling the app, I can see that large MemoryStreams are created when I type Ctrl+C on the keyboard and I can see that the CPU is spending a lot of time in HelixToolkit.Wpf.HelixViewport3D.Copy(). I think it is copying the screen view as a bitmap or something like that.
It looks to me like the "Ctrl+C" is already pre-assigned behind the scenes, but I cannot find any documentation about it.
How would you overwrite this key binding to call my own copy code?

Related

WPF Button's Command-Binding not working when launched from WinForms

I have a UserControl with two buttons in my Window. The UserControl has it's own DataContext with two corresponding Commands.
Naturally, the binding on the buttons was written like this
Command="{Binding SaveCommand}"
However, we have two launch mechanisms for our modules: one is via a WPF launcher and the other is via our old WinForms menu. If we use the WinForms menu, the binding does not work anymore. Instead the following Binding was the only way to make it work.
Command="{Binding DataContext.SaveCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Is this due to WinForms in combination with the way commands bubble up or something along those lines?
Note 1: Other modules seem not to be afflicted somehow. It might really be this exact structure / the double DataContext (window/control)
Note 2: It might be worth noting that we use Telerik's RadButton instead of regular buttons.

How can I register a command in a user control that also applies to the hosting window or rest of the application

I am writing a user control and I have a requirement to define "hotkeys". This could be for example: Ctrl+S to save the control layout as bitmap. But they are supposed to be application global.
I found out that I can define a command like this in my user control:
<UserControl.InputBindings>
<KeyBinding Command="{Binding ExitCommand}"
Key="{Binding ExitCommand.GestureKey}"
Modifiers="{Binding ExitCommand.GestureModifier}" />
The bindings are from my own Command object and it works. But only in the control (or if it has focus).
How can I declare something that will also work for the hosting application globally?
Or if not in xaml could I code something without knowing the rest of the application?
Or can this only be done from the application level?

Class Library not including images

I have a class library that is essentially a collection of forms to be run. Consider it a module/plugin in a larger program, that can be developed independently, all the larger program cares about is the DLL (and interface).
Running the main form of the class library is fine and works well. My issue is with pictures. I've set up an Images folder in the class library, added an image, set it's Build Action to Embedded Resource and then rebuilt the project, but the images won't appear in the main program.
XAML:
<Button x:Name="btnAdd" Command="{Binding Add}">
<StackPanel Orientation="Horizontal">
<Image x:Name="imgAdd" Source="Resources/Add.png"/>
<Label>New</Label>
</StackPanel>
</Button>
The interesting part though, is that if I create a BitmapSource in code-behind and assign it to imgAdd in the constructor of the form, it works as expected. Does anyone have any ideas as to why this might be the case?
Use Pack URIs for your images.
<Button x:Name="btnAdd" Command="{Binding Add}">
<StackPanel Orientation="Horizontal">
<Image x:Name="imgAdd" Source="pack://application:,,,/ReferencedAssembly;component/Resources/Add.png"/>
<Label>New</Label>
</StackPanel>
</Button>
It turns out that the correct Build Action is actually Resource rather than Embedded Resource. Thinking about it now, Embedded Resource does seem more like a reference to a Resource in another DLL.
I inadvertently found the answer in this post while trying to improve my code.

Without Interactivity.dll: Alternative to MVVMLight's EventToCommand

In our current C# project, we use the MVVM light framework and its EventToCommand feature to bind events to commands (as also mentioned in this SO thread).
We use it for example like this:
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<cmd:EventToCommand CommandParameter="{Binding SelectedItem, ElementName=SelectTree}"
Command="{Binding Path=SelectTreeGotFocusCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
My question is: What is the easiest way to achieve the same behaviour (i.e., EventToCommand, not limited to GotFocus) without using System.Windows.Interactivity?
To avoid the XY problem, here is some background:
We are developing an addon for an already existing main application, on which we do not have any influence. Our addon is served as a dll which is used by this main application.
So far, we used XAML code as given above (i.e., using System.Windows.Interactivity and EventToCommand). However, the last release of the main application contains an old version of System.Windows.Interactivity (so far, it was not included at all) which doesn't support this.
This means that using the old Interactivity.dll will cause our addon to be non-functional. However, overwriting the dll with the new version we need will cause issues with parts of the main application.
I read about using two different versions of the same dll in a project (for example here) but this seems to be quite involved. Since there are only a few places we use this construction, I thought that replacing it with code not using Interactivity.dll might be easier.
If you switch to the Microsoft.Xaml.Behaviors.Wpf nuget package and change your namespace declarations to
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
you can use the InvokeCommandAction like so:
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus"}">
<i:InvokeCommandAction Command="..." CommandParameter="..."/>
</i:EventTrigger>
</i:Interaction.Triggers>

OneWayToSource in Silverlight and UpdateSource issue

I'm facing some problems binding a CommandParameter to its own Command in an application built using Prism 2.2 as MVVM . Let me introduce what it's happening.
I've got a customized listbox with a property named NumPageElements, and a couple of buttons to scroll through the list who needs that property. A simplified xaml of what I need (and works) in wpf is:
<Button x:Name="PageDownButton" Command="{Binding PageDownCommand}" CommandParameter="{Binding ElementName=ItemsListBox, Path=NumPageElements}" />
<Custom:MyOwnListBox x:Name="ItemsListBox" x:NumPageElements="{Binding ElementsPerPage, Mode=OneWayToSource}" >
. . .
</Custom:MyOwnListBox>
To have the same behaviour in Silverlight I wrote this xaml:
<Button Name="PageDownButton" Command="{Binding PageDownCommand}" CommandParameter="{Binding ElementName=ItemsListBox, Path=NumPageElements}" />
<Custom:MyOwnListBox Name="ItemsListBox" NumPageElements="{Binding Path=ElementsPerPage, Mode=TwoWay, UpdateSourceTrigger=Explicit}" >
. . .
</Custom:MyOwnListBox>
PageDownButton is an IApplicationCommand, ElementsPerPage is a property exposed by the presenter.
Now, the first time I open this view the buttons made in that way look enabled but they aren't 'clickable'. If I switch to a different view and I go back to the view with those button, they finally catch the correct behavior. It looks like it doesn't initialize correctly the first time the condition of the command (infact they should be disabled until I insert an item in the listbox), as if the parameter given via the CommandParameter property isn't initiliazed correctly. But I can't understand why switching between the views make it works.
I suspected I should force the UpdateSource of the bindings (I did it for ItemsListBox.NumPageElements and for PageDownButton.CommandParameter) after the view has been loaded, but doing it in the code behind was not of any help.
What I am doing wrong?
Thanks for any reply,
Mat.

Categories