So I have a ListView made up of multiple InkCanvas controls (which basically are pages of a document). Now I would like to use a global InkToolbar for all of my pages (the InkCanvas controls). However, InkToolbar only allows to bind to a single TargetInkCanvas object and I am not really sure how I can get around that and design my pages so they all share the same InkToolbar.
How to use a global InkToolbar for multiple InkCanvas controls?
InkToolbar only allows to bind to a single TargetInkCanvas in xaml code with x:bind scheme. If you do want a global InkToolbar, please try to set TargetInkCanvas in the code behind when you use the specific InkCanvas.
private void Button_Click(object sender, RoutedEventArgs e)
{
inkToolbar.TargetInkCanvas = MyInkCanvas;
}
Ok so I found a workaround. The solution is rather unelegant but it does work. It is possible to handle pointer input in an InkCanvas prior to processing. This can be done
using CoreInkIndependentInputSource class as follows:
CoreInkIndependentInputSource core = CoreInkIndependentInputSource.Create(inkCanvas.InkPresenter);
core.PointerEntering += PointerEntering;
Then in my PointerEntering event handler, I can change propagate the signal that the current canvas should be bound to the InkToolbar (in my case I had to use VisualTreeHelper to propagate the information to the parent ListView).
Related
In cppwinrt (xaml not yet available) I have a handler for the PointerEntered event of a Button, and it works fine. But in attempting to remove the default hover behavior of this Button, which displays as an image, it seems I may need to handle the OnPointerEntered event instead - I have seen solutions that involve using a xaml trigger and this would seem to be a code equivalent. But OnPointerEntered has a different argument list, and I can't find a way to invoke it that will build. Here is how the PointerEntered event handle is successfully declared:
button.PointerEntered([&](winrt::Windows::Foundation::IInspectable const & sender, Windows::UI::Xaml::RoutedEventArgs const & args) { EnteredButton(); });
That builds and correctly calls EnteredButton. But
button.OnPointerEntered([&](winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const & e)
{
EnteredButton();
});
will not build - I am declaring it incorrectly but am not sure how, after trying a number of variants. (Using the fully-qualified names is maybe not necessary, but seems not to hurt in either case). Can OnPointerEntered be used in cppwinrt, and how would it be declared if so? I have tried using IPointerRoutedEventArgs instead of PointerRoutedEventArgs with no effect. Or - if anyone knows a different way to disable the hover effect in a Button created with cppwinrt, that would work.
You can't do what you're asking. Echoing IInspectable's comment:
PointerEntered is an event on Windows::UI::Xaml::UIElement. Your code is correctly declaring a handler for it.
OnPointerEntered is not an event, so there is no way to handle it. It is an overridable method for which you can provide your own implementation.
I have a TextBlock and its Text property is bound to a ViewModel property. The binding is Oneway.
When I change the Text property of the Control from the xaml.cs the binding gets broken. If the binding is TwoWay I don't have this problem but the source property is updated too. Is it possible to have OneWay binding and change the target property value without braking the binding?
I suggest a workaround, like setting the Binding to TwoWay and ignore the update in the property. Something like this:
private string textValue;
public string TextValue
{
get { return textValue; }
set
{
:
}
}
Now the Property can no longer be set by the view.
Although no code is provided, this scenario typically occurs when you have bound a control to a view model and at a later stage your logic tries to update the value in the control programmatically.
You should not try to do this, that is define multiple sources of the value for a control. If you bind the control to a property on the view model, then to update the value in the control you should update the field in the view model.
If you were to set the value of a bound control programmatically at runtime so that it no longer matched the bound object value, when some other event causes the control binding to be re-evaluated, the value that you have provided programmatically would be overwritten again, you could easily end up with a scenario where the value you provided programmatically is never visible to the user.
In this scenario you should either:
Add a new property to the view model, bind this value to the control, then your program logic can set this value equal to the original property when the data is loaded, and updated when you need to
Not use bindings at all, always write to the control programatically that way you tightly control when the value is updated.
There is a workaround to this if you absolutely must have one. if you are using compiled bindings (x:Bind), then because the bindings are compiled it is possible to call SetValue on the bound dependency property at runtime and the previously compiled bindings will still be evaluated. However I advise against exploiting this because it makes your code a lot harder to follow and debug, when bindings are used, we tend not to look for code that directly addresses and sets control values.
I don't know C# events very well so I have difficulties in understanding some code I found in internet
Inside the code behind of a view file there is the following method:
public void SavingMesBoxClosedHandler(object sender, object args)
The DisplayMessageBox class is derived form FrameworkElement and defines the following event:
public delegate void MessageBoxClosedHandler(object sender, object args);
public event MessageBoxClosedHandler DialogClosed;
Inside the xaml of the view:
<DisplayMessageBoxDemo:DisplayMessageBox
// some dependency properties here
DialogClosed="SavingMesBoxClosedHandler"/>
I thought I could use only dependency properties, while DialogClosed is an event.
Which is the magic to map a method of the view to an event in DisplayMessageBox class using only its name ?
Why don't I have to use a binding ?
Is there an easy way to assign a viewmodel method as the event handler of DialogClose ?
May be I didn't use the correct terms in my last question. To put in other words I want to call a method inside my viewmodel, not in the view as in the example I reported above.
You don't have to use only dependency properties in XAML. You can use normal properties just as well. Dependency properties are a necessity when you use DataBinding, as you point out. In the case you mention there seems to be no need to use DataBinding because you will not use different handlers depending on your DataContext. If you want to stick to the MVVM pattern and keep the event handling logic in your view model, you can use EventTrigger: http://www.kunal-chowdhury.com/2010/11/using-eventtrigger-in-xaml-for-mvvm-no.html
I'm trying the MVVM pattern and I've run into a problem.
Here's how I instantiate my model:
<common:LayoutAwarePage
...
...(omitted boiler plate generated lines here)
...
...
mc:Ignorable="d">
<common:LayoutAwarePage.DataContext>
<local:TextGameClientModel x:Name="textGameClientModel"/>
</common:LayoutAwarePage.DataContext>
But when I try to use it, I get a NullReferenceException because this.textGameClientModel is NULL:
public MainPage()
{
this.InitializeComponent();
this.textGameClientModel.runsPublished += textGameClientModel_runsPublished;
}
I've also tried the same line in the Page's OnNavigateTo handler, and also in the OnLoaded handler, but with the same result.
Where is the right place to hook up my event handler?
(Please don't let my code-behind in an MVVM project distract you from the question. My use of a RichTextBox has forced me to color outside the lines a little.)
I actually wrote an answer about the WPF Creation Steps fairly recently, however that's not the problem in this case.
In this case, you are setting the DataContext in your XAML, however that's not the same as setting the textGameClientModel property
You need to do something like this to set the property equal to your DataContext first
this.textGameClientModel = this.DataContext as GameClientModel;
or simply cast your DataContext as your class to setup the event
((GameClientModel)this.DataContext).runsPublished += textGameClientModel_runsPublished;
As a side note, I never recommend hardcoding the DataContext into a UserControl like you have. By doing so, you are preventing any other DataContext from getting passed to the UserControl, which kind of defeats one of the biggest advantages of WPF/MVVM, which is having separate UI and data layers.
I have a functional MVVM patterned SL app with a RadWindow (essentially a ChildWindow), that I would like to remove the code-behind in my view that shows the window using its ShowDialog. Both the main view and the window is bound to the same ViewModel if that helps.
The button has both a ViewModel command using a MVVMLight RelayCommand to handle setting state as well as the event handler in the View.
The ultimate solution/pattern will be reused 20+ times so something better than code-behind would be great.
Thoughts?
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
var window = new RadWindowTest.Controls.ChildWindow1();
window.Closed += new System.EventHandler<Telerik.Windows.Controls.WindowClosedEventArgs>(window_Closed);
window.ShowDialog();
}
In this case I would suggest you implement DialogService. This service you can inject into your view model, for testing you will have to inject an instance that does not depend on the view, thus maintaining testability. You can use the ViewModelLocator to make this service available to your application.
Another approach would be to implement a ViewBase class that implements an interface that allows you to display the dialog. This interface is now used by the ViewModel to display a dialog. Again to test you need to provide a different implementation of the interface. A sample can be found here.
Both ideas revolve around the same concept of factoring out the function that shows the dialog. In order to strictly de-couple the View and the ViewModel you will have to think about how the ViewModel specifies which dialog has to be shoen, and how the dialog resut or dialog model is returned to the calling ViewModel.
Which approach is better is open to your judgement. Personally I prefer the first approach as I do not have to inherit the views from a common base class.
PS: Use a command to get to the point in your ViewModel where you want to show the dialog. Using a dialog service should need no code behind.