How to bind Variables of View to ViewModel in WPF MVVM? - c#

I have a created a window ( WPF and MVVM ) - say PrintWidow ( so I have PrintWindow.xaml , PrintWindow.xaml.cs , PrintWindowViewModel.cs- viewmodel)
Now I am going to use(call) this PrintWindow obj from some other class on button click or on some command trigger , I want to set Document Source for this PrintWindow(following MVVM).
How would I do this ? I created a PrintDocument object in PrintWindow.xaml.cs and tried to bind it as follows : (obviously just a blank try - as I cannot do this declaration in XAML)
private PrintDocument printDocuementView;
public PrintDocument PrintDocuement
{
get { return printDocuementView; }
set { printDocuementView = value; }
}
//constructor
public PrintWindow()
{
InitializeComponent();
this.DataContext = new PrintViewModel();
Binding b = new Binding();
b.Source = printDocuementView;
b.Path = new PropertyPath("PrintDocumentCommand"); // "PrintDocumentCommand" is defined in View Model class and is responsible to set the `PrintDocument` object there.
}
This code (obviously) doesn't work. How should I go about it.
Summary : I want to open PrintWindow from another window and eventually set some Property of PrintWindow from code behind of the 'other widow' object.The query is - where should this property go? View ? ViewModel? ?? puzzzeled
I have googled for answers - but couldn't relate any to my problem.
I am a Freshman for WPF and a Rookie for MVVM.

Since your PrintDocumentCommand is in your PrintViewModel but you're setting the Source of this Binding to an instance of the PrintDocument-Class, it can't be found, because the Binding is looking for the PrintDocumentCommand in PrintDocument-Class.
If you want to open the PrintWindow from another Window, place the PrintDocument-Property and the PrintDocumentCommand in the ViewModel of the other Window. Now your function that is executed through the PrintDocumentCommand could look like:
private void Print()
{
PrintWindow pw = new PrintWindow(PrintDocument);
pw.ShowDialog();
}
The constructor of your PrintView could be like:
public PrintWindow(PrintDocument pd)
{
InitializeComponents();
this.DataContext = new PrintViewModel(pd);
}
and now you can access the PrintDocument in your PrintViewModel.

Related

How to be get propertychange event from Uc1 to Uc2 on one Windows (WPF)

I have a problem with WPF binding. I have frmBill.xaml Window with two usercontrol like that:
<materialDesign:TransitionerSlide OpeningEffect="{materialDesign:TransitionEffect SlideInFromRight}">
<materialDesign:TransitionerSlide.BackwardWipe>
<materialDesign:SlideWipe Direction="Right"/>
</materialDesign:TransitionerSlide.BackwardWipe>
<materialDesign:TransitionerSlide.ForwardWipe>
<materialDesign:SlideWipe Direction="Left"/>
</materialDesign:TransitionerSlide.ForwardWipe>
<local:ucBill_Information/>
</materialDesign:TransitionerSlide>
</materialDesign:Transitioner>
</Grid>
And I have two ViewModel as ucDeclarationViewModel.cs and ucBill_ViewModel for this. And using Thread with claim based to bind data between this by using a button click event (I got it), but I can not bind data from VM to V (Using prism). I know my issue, but I dont know how to solve it :(. Please help me.
private ucBill_InformationViewModel _ucBlvm;
public ucBill_InformationViewModel ucBIvm { get => _ucBlvm; set => _ucBlvm = value; }
public ucBill_Information()
{
InitializeComponent();
this.DataContext = ucBIvm;
}

Routed Command Implementation in WPF

I have simple ICommand-Bindings working, however I have Buttons inside an ItemsControl and wanted to get the sender information, like with the normal Routed-Events (object sender, e RoutedEventArgs) and this seems not to be possible with the normal ICommands, right?
I am a little bit lost here.
I currently use the Prism 6 DelegateCommand-Class to get things working. It looks like this:
private ICommand _selectCommand;
public ICommand SelectCommand
{
get
{
return _selectCommand ?? (_selectCommand = new DelegateCommand<object>(SelectImage));
}
}
private void SelectImage(object image)
{
var img = (BitmapImage)image;
var index = Scans.IndexOf(img);
this.CurrentIndex = index + 1;
ImageToDisplay = img;
}
How I can I get the RoutedCommand to work?
A view model is not supposed to be accessing or even know about any view element.
You should bind a target property of the control in the view to a source property of the view model that you can simply set in your SelectImage method when your command gets executed.

Passing data between user controls in wpf

I have a user control with a button which when clicked opens a new user control.
private void Button_Click(object sender, RoutedEventArgs e)
{
Window window = new Window
{
Title = "Window2",
Content = new UserDataControl2()
};
window.ShowDialog();
}
I need to pass a collection to the new user control. How can I do it?
The easiest way is to create a custom constructor for your user control.
// Button_Click event
Window window = new Window
{
Title = "Window2",
Content = new UserDataControl2("My Data");
};
// User Control class.
string _info;
public UserDataControl2(string info)
{
_info = info.
};
You could also create a method or property in the user control to receive the data as well. Use whichever seems more appropriate in your context.
The best way is passing object to DataContext of this Window. For this you will need to create a class where store this parameters (ViewModels) and after "binding" to the Window (View). After you can pass this object assigning to Datacontext.
Look to MVVM model to understand better what I mean.
MVVM Pattern Made Simple
MVVM in Depth

Retrieve the DataContext of the Content set by using ContentSource property

I need to get the DataContext of the View set by using ContentSource property of the ModernWindow, Could you please help.I am using MVVM framework with Modern UI. The ViewModel code from where I need to show another window is as follows,
public void ShowPrompt()
{
this.PromptWindow = ObjectFactory.GetInstance<IPromptWindowViewModel>().Window as ModernWindow;
this.PromptWindow.Owner = Application.Current.MainWindow;
this.PWPMainViewModel.PromptWindowsCollection.Add(this.PromptWindow);
// Here I need to get the DataContext of PromptWindow's Content
this.PromptWindow.Show();
}
I did some debugging and found that by inherting IContent interface from ModernUI in the 'OnNavigatedTo' event
public void OnNavigatedTo(FirstFloor.ModernUI.Windows.Navigation.NavigationEventArgs e)
{
IPWPMainViewModel pwpMainViewModel = ObjectFactory.GetInstance<IPWPMainViewModel>();
pwpMainViewModel.PromptMainsCollection.Add(new ContentControl { Content = e.Content });
IPromptMainViewModel promptMainViewModel = ((UserControl)e.Content).DataContext as IPromptMainViewModel;
}
Here I am able to get the DataContext of the ModernWindow's Content i.e. of type 'IPromptMainViewModel' but here its very difficult to map/load the views into this ModernWindow as there are multiple instances of views, but I would like to do it in the ViewModel where 'ShowPrompt()' is present as there the Model will be associated with the View correctly so I can map there the views easily.
Thank you.
To get this done, I set the Content of the ModernWindow by myself (as shown in below code in a method in a ViewModel) without using the ContentSource DependencyProperty, If we use the ContentSource property it will be set for a ModernFrame type by the ModernWindow itself creating its Content instance after Navigation to that View completes in some method in ModernFrame class from ModernUI for WPF by using ModernFrame's Source DependencyProperty.
public void ShowPrompt()
{
this.PromptWindow = ObjectFactory.GetInstance<IPromptWindowViewModel>().Window as ModernWindow;
this.PromptWindow.Title = string.Concat("Control ", this.PromptOriginsEntity.PromptOriginsIdentity);
this.PromptWindow.Tag = this.PromptOriginsEntity.PromptOriginsIdentity;
this.PromptWindow.Owner = Application.Current.MainWindow;
// Store Window object in PromptWindowsCollection
this.PWPMainViewModel.PromptWindowsCollection.Add(this.PromptWindow);
this.PromptWindow.Show(); // inorder to retrieve the ModernFrame the ModernWindow is to be shown first
ModernFrame frameContent = (ModernFrame)this.PromptWindow.Template.FindName("ContentFrame", this.PromptWindow);
UserControl userControl = new UserControl { Content = GetView<IPromptViewModel>(), Tag = this.PromptOriginsEntity.PromptOriginsIdentity };
frameContent.Content = userControl;
this.PWPMainViewModel.PromptsCollection.Add(userControl);
IPromptViewModel promptViewModel = (IPromptViewModel)((IView)userControl.Content).DataContext;
promptViewModel.PromptEntity.Identity = this.PromptOriginsEntity.PromptOriginsIdentity;
}
I've uploaded a prototype app at https://wpfmvvmsamples.codeplex.com/SourceControl/latest
Thanks.

Insert Text and Image in HubTile after online-content is loaded

I'm new to WP8 and follow many tutorials. For parts of the menu I use a viewModel with NotifyPropertyChanged. When I get my list of news articles it creates a viewModel and displays it in a longListSelector.
But also I want to make 1 HubTile with the image and some preview-text of the first article. Is there a nice way to send some event to the .xaml.cs? Or do I have to make another viewModel for this one HubTile and make a binding?
Ony try was to make such a variable:
private bool _isDataLoaded = false;
public bool IsDataLoaded
{
get
{
return _isDataLoaded;
}
set
{
if (value != _isDataLoaded)
{
_isDataLoaded = value;
NotifyPropertyChanged("IsDataLoaded");
}
}
}
The same thing is used with "IsLoading"-variable to create a loading-indicator in the systemTray:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("MainPage_Loaded-Funktion");
Binding binding = new Binding("IsLoading") { Source = DataContext };
BindingOperations.SetBinding(
prog, ProgressIndicator.IsVisibleProperty, binding);
binding = new Binding("IsLoading") { Source = DataContext };
BindingOperations.SetBinding(
prog, ProgressIndicator.IsIndeterminateProperty, binding);
prog.Text = "Lade aktuelle Inhalte...";
}
Can I use this to call a function, when my variable is set and I get a notification?
The solution that helped me out was this:
<toolkit:HubTile Message="{Binding OnlineNews[0].TeaserText}"/>
Didn't know that you can access the viewModel like that. Thanks to Toni Petrina!

Categories