Region not loaded by the RegionManger - prism

in a prism 6 based application,
this is a part of my shell, and QuickAccessToolBar region defined like this:
<telerik:RadRibbonView>
<telerik:RadRibbonView.QuickAccessToolBar>
<telerik:QuickAccessToolBar prism:RegionManager.RegionName="{x:Static inf:RegionNames.QuickAccessToolBarRegion}"/>
</telerik:RadRibbonView.QuickAccessToolBar>
The RegionManger will not be loads the region,
and when will replace the definition above(just for demo purposes) by this :
<telerik:RadRibbonView >
<ContentControl prism:RegionManager.RegionName="{x:Static inf:RegionNames.QuickAccessToolBarRegion}"/>
The RegionManager loads the region!
my question is:
what's Wrong in my XAML ? my be the region was defined inside a complex property?
Can you guide me,
thanks in advance.
best regards.
Solution :
Very good answer Brian, it works like a charm,
as Brian said:
first of all we name the targeted element:
<telerik:RadRibbonView.QuickAccessToolBar>
<telerik:QuickAccessToolBar x:Name="QuickAccessToolBar"/>
</telerik:RadRibbonView.QuickAccessToolBar>
in the code behind (the Shell in my case) :
public Shell(ShellViewModel viewModel, IRegionManager regionManager)
{
InitializeComponent();
DataContext = viewModel;
RegionManager.SetRegionName(QuickAccessToolBar,RegionNames.QuickAccessToolBarRegion);
RegionManager.SetRegionManager(QuickAccessToolBar, regionManager);
}
Where RegionNames.QuickAccessToolBarRegion ="QuickAccessToolBarRegion" and regionManager is the RegionManager resolved by unity container
Thank you very much Brian, good night :)

My guess is that the QuickAccessTolbar is not part of the visual tree, so the region manager can't find it. Since this is a Telerik control, I am not aware of how they architected their control. You might have to do this in code behind instead.
First set the region name, then set the RegionManager using the attached properties.
RegionManager.SetRegionName(quickToolbar, name);
RegionManager.SetRegionManager(quickToolbar, rm);

Related

Where did ViewLocationExpanderContext.IsPartial go?

In Core MVC if you want the razor view engine to look for views in places other than the default locations then a new ViewLocationExpander can be added in the ConfigureServices method in the startup.cs like so
services.Configure<RazorViewEngineOptions>(options => {
options.ViewLocationExpanders.Add(new ViewLocationExpander());
});
Where the ViewLocationExpander class implements IViewLocationExpander. That class typically has access to the ViewLocationExpanderContext, and in RC1 that context contained an IsPartial property. This property was useful if the location expander wanted to specify different view locations for partial views than regular views.
I see that in RC2 this IsPartial property is gone. However, I do see that there is a IsMainPage property but I can't find any documentation on it.
Does anyone know if the property basically just the inverse of the old IsPartial property?
Yes, the IsMainPage property is as you've said - the inverse of IsPartial. As Pranav has pointed out in the comments, you can see the commit and reasoning for the change here.
Glad to see I'm not the only one that was caught out by this change!

SubreportProcessing event handler cannot access my viewmodel due to being on a different thread

I have a WPF application that is utilizing the reporting tools included with Visual Studio 2010. I've had some other problems that I've solved by creating a graph of objects that are all marked as serializable, etc., as mentioned on various other web pages.
The ReportViewer control is contained in a WindowsFormsHost. I'm handling the SubreportProcessing event of the ReportViewer.LocalReport object to provide the data for the sub report.
The object graph that I'm reporting on is generated in my viewmodel, and that viewmodel holds a reference to it. The SubreportProcessing handler is in my code behind of my window (may not be the best place - but I simply want to get the ReportViewer working at this point).
Here's the problem: In my event handler, I'm attempting to get a reference to my viewmodel using the following code:
var vm = DataContext as FailedAssemblyReportViewModel;
When the handler is called, this line throws an InvalidOperationException with the message The calling thread cannot access this object because a different thread owns it.
I didn't realize the handler might be called on a different thread. How can I resolve this?
I attempted some searches, but all I've come up with is in regards to updating the UI from another thread using the Dispatcher, but that won't work in this case...
I solved this problem using something I believe is a hack, by adding the following function:
public object GetDataContext() {
return DataContext;
}
And then replacing the line of code from my question with:
object dc = Dispatcher.Invoke(new Func<object>(GetDataContext), null);
var vm = dc as FailedAssemblyReportViewModel;
However, this seems like a hack, and I might be circumventing some sort of safety check the CLR is doing. Please let me know if this is an incorrect way to accomplish this.
That's a nasty problem you have there.
Why don't you use in the view a content presenter which you bind to a windows form host?
And in the view model you would have a property of type of type WindowsFormsHost. Also,in the view model's constructor you could set the windows form's host Child property with the report viewer.
After that is smooth sailing, you could use your report viewer anywhere in your code. Something like this:
View:
<ContentPresenter Content="{Binding Path=FormHost}"/>
ViewModel:
private ReportViewer report = new ReportViewer();
private WindowsFormsHost host = new WindowsFormsHost();
public WindowsFormsHost FormHost
{
get {return this.host;}
set
{
if(this.host!=value)
{
this.host = value;
OnPropertyChanged("FormHost");
}
}
}
public ViewModel() //constructor
{
this.host.Child = this.report;
}
After that happy coding. Hope it helps.

MVVM How to get away from Code Behind Events

After looking at some of the MVVM toolkits(MVVM Light, SimpleMVVM) out there the common theme seems to try to use as many blendable events as possible and not use codebehind.
I am not sure how to do all the events. For instance 2 events come to bind when doing windows phone 7.
OnNavigatedTo/From
On Load
Does anyone have examples on how to do this in MVVM? I am using SimpleMVVM but I would hope that the examples might be similar and maybe MVVM light toolkit or even just general MVVM tutorial showing this might help.
I only found ones that show how to do like the button click.
Edit
I am sort of confused on when to use code behind events or use blend events to commands.
For instance in the the MVVM Light tutorials they use MVVM for navigation but why is that better than using a codebehind event?
I am also kinda confused now when people say
Codebehind isn't evil; its the mix of business logic and codebehind
that is problematic. Let your UI handle UI tasks in your codebehind.
Well in the MVVM light examples they have "isbusy" in one of the examples where when the list or whatever it was(forgot) is loading a "loading sign comes up". This was all done in ViewModel and not a codebehind event.
So this seems kinda conflicting to me(maybe I am missing something). What also puzzles me is that if the ViewModel does not know anything about loading how do you know when the loading has started or finished?
As HighCore commented, use EventToCommand. It's pretty simple to use, although you'll need the Blend SDK first.
...
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
...
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding GetTweetsCommand}" CommandParameter="Twitter" />
</i:EventTrigger>
</i:Interaction.Triggers>
Also, just a general point on the code-behind: having UI-related functionality in the code-behind isn't the worst thing in the world! It's separate from your ViewModel and it's in a logical place. However, I find behaviours easier to test. For example, using a class inheriting from TargetedTriggerAction allows a storyboard to be controlled by both property changes and controls:
public class ImageAnimationTrigger : TargetedTriggerAction<Storyboard>
{
protected override void Invoke(object parameter)
{
if (Target == null)
return;
if (parameter is DependencyPropertyChangedEventArgs)
{
DependencyPropertyChangedEventArgs args = (DependencyPropertyChangedEventArgs)parameter;
if ((bool)args.NewValue)
Target.Begin();
else
Target.Stop();
}
else if (parameter is RoutedEventArgs)
{
RoutedEventArgs args = (RoutedEventArgs)parameter;
if (!(args.OriginalSource as Button).IsEnabled)
Target.Begin();
else
Target.Stop();
}
}
}
I use this behaviour with a PropertyChangedTrigger as follows:
<i:Interaction.Triggers>
<ic:PropertyChangedTrigger Binding="{Binding Loading}">
<behav:ImageAnimationTrigger TargetName="animStoryboard" />
</ic:PropertyChangedTrigger>
</i:Interaction.Triggers>
As Laurent Bugnion says, use the code-behind if you need to!
1) Unfortunately I didn't find good examples so you are on your own.
2) if you keep your code-behind blank (by using commands instead of button click) you concentrate your code in ViewModel only. I can see two points of benefits:
a) in case you use one ViewModel for different Views (and have some common commands in several vies),
b) in case you use some private variables/methods of your ViewModel which are not available in the View.
3) You may use RaisePropertyChanged to load (reload) data, load data in ViewModel constructor to avoid using OnNavigatedTo or something else.

Can we have a Master UserControl act as an interface to inherit from that?

In my windows phone 8 app I need to have a few UserControl which all of them have same functions (only the header not the body). I am wondered if i can have some thing like interface so i can inherit from that? (i could do it in ios with UIViewController)
If you're extending the same basic idea you may be best to look at creating a Custom Control and then adding what your body as Content inside it the control. You can then re-skin your custom control as you need in each case (and learn more about how controls work as a side-effect).
It's a bit more work than creating a UserControl, but it sounds appropriate for what you're doing and is the idiomatic way of solving this kind of problem in XAML/.NET (WP, Windows Store, WPF).
There is a good article on the differences between User Control and Custom Controls on WindowsPhoneGeek.
public abstract class MasterUserControl : UserControl
{
[...]
}
public class MyUserControl : MasterUserControl
{
}
Something like that?

Switch between Views in different Modules using Prism and Unity

I am making a proof of concept WPF application with Prism 4 and Unity, but I run into some basic problems.
In our solution we have the following projects:
-AppName.Desktop
-AppName.Modules.ModuleA
-AppName.Modules.ModuleB
Having followed some tutorials, explored some examples and searched the internet, I wasn't able to find a suitable answer to a very rudimentary question; how can I switch between two views in different DLL's.
The first view (ModuleAView) is loaded in the Initialize method of ModuleA:
public void Initialize()
{
regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ModuleAView));
}
When I click in ModuleAView (or on a button in ModuleAView) I want to switch to ModuleBView.
public bool SomeEventInModuleAView(SomeEventParams e)
{
Uri viewNav = new Uri("ModuleBView", UriKind.Absolute);
regionManager.RequestNavigate(RegionNames.MainRegion, viewNav);
}
Obviously this won't work, since ModuleA doesn't know where to find ModuleBView. I have read about changing the URI with pack/application/component etc, but I can't seem to make it work.
I was thinking something like this:
Uri("pack://application:,,,/AppName.Modules.ModuleB;component/Views/ModuleBView.xaml", UriKind.Absolute);
Since loading modules from different assemblies is one of the purposes of Prism, I think it's strange that there aren't any examples in the Prism download to show how this works.
I have found the answer. I totally forgot to register the second view.
Check the solution over here: http://compositewpf.codeplex.com/discussions/402860#post940396

Resources