Dialog Window Change the Main Window - wpf

how to make something like this:(Screen is not from my app)
When is change the button in dialogBox, it automatically change the Bitmap in MainWindow...
I hope you understand my prob ;d
So how can i make this dialog window ?
Or how can i get access to Mainwindow variables from dialogWindow?

If you have no architecture to support that (like MVVM), you can simply use the Application object in you dialog code-behind:
MainWindow mainWindow = Application.Current.MainWindow as MainWindow;
mainWindow.button1.Content = "Dialog rename me";
Application object is set on your application execution and is global.

Define a class where you put all information relevant to your item.
All properties uses NotifyPropertyChanged.
One of this property is the Title.
So now in your main window you have a TextBlock bound your object title (it might be within a control that draws the object and write the title above), and when you click on a button it opens another window. In the constructor( new()) of the second window, you give the drawn object as argument.
So when you change the title in the second window, it gets updated in the first.

Related

Referencing MainWindow's content in MaterialDesign's DialogHost

I'm developing a WPF application using Material Design in XAML library. I'd like to use a dialog box to display error messages. In the documentation I've read that in order to dimm and disable content behind the dialog box I have to put it in the DialogHost tag, right after DialogHost.DialogContent
This is what I have right now:
<Window>
<md:DialogHost>
<md:DialogHost.DialogContent>
Content of my dialog box
</md:DialogHost.DialogContent>
My window's content wrapped in grid.
</md:DialogHost>
</Window>
The problem is: I'm planning to add few more dialog boxes for different purposes and I don't really know how to do that, since I have to put the rest of the code inside the DialogHost tag, which in my opinion would be a bit messy.
Instead I would like to achieve something like this:
<Window>
<Grid>
<md:DialogHost>
<md:DialogHost.DialogContent>
Content of my dialog box
</md:DialogHost.DialogContent>
Reference somehow the rest of the window's content
</md:DialogHost>
Window's content
</Grid>
</Window>
I tried using ContentPresenter but I'm getting error saying that the property Content cannot be bound to visual element.
If the idea described above is impossible to do, how can I use more than 1 dialog boxes? Because nesting one in another would result in a big messy code.
You should first remove the <md:DialogHost.DialogContent>from your main window and create an <UserControl>for each dialog box you need.
In the ViewModel class using such a dialog you must instantiate this <UserControl> and provide this instance as parameter for the DialogHost.Show method.
Dim view As New MyDialog1() With {.DataContext = Me}
Dim obj as Object = Await MaterialDesignThemes.Wpf.DialogHost.Show(view)
if obj IsNot Nothing Then
'do something
EndIf
I this (VB) example an MyDialog1 View class is instantiated using the DataContext of the VieModel class allowing the View class to access ViewModel class properties. Then the DialogHost.Show method is invoked. The View class can provide user response which is evaluated after closig of the View class.

ShowDialog() behind the parent window

I am using ShowDialog() with WindowStyle = WindowStyle.SingleBorderWindow; to open a modal window in my WPF (MVVM) application, but it lets me navigate to parent window using the Windows taskbar (Windows 7).
I've found an answer here: WPF and ShowDialog() but it isn't suitable for me because I don't need an "always on top" tool window.
Thanks in advance
Try setting the Owner property of the dialog. That should work.
Window dialog = new Window();
dialog.Owner = mainWindow;
dialog.ShowDialog();
Edit:
I had a similar problem using this with MVVM. You can solve this by using delegates.
public class MainWindowViewModel
{
public delegate void ShowDialogDelegate(string message);
public ShowDialogDelegate ShowDialogCallback;
public void Action()
{
// here you want to show the dialog
ShowDialogDelegate callback = ShowDialogCallback;
if(callback != null)
{
callback("Message");
}
}
}
public class MainWindow
{
public MainWindow()
{
// initialize the ViewModel
MainWindowViewModel viewModel = new MainWindowViewModel();
viewModel.ShowDialogCallback += ShowDialog;
DataContext = viewModel;
}
private void ShowDialog(string message)
{
// show the dialog
}
}
I had this problem but as the Window was being opened from a view model I didn't have a reference to the current window. To get round it I used this code:
var myWindow = new MyWindowType();
myWindow.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
You can use: myWindow.Owner = Application.Current.MainWindow;
However, this method causes problems if you have three windows open like this:
MainWindow
|
-----> ChildWindow1
|
-----> ChildWindow2
Then setting ChildWindow2.Owner = Application.Current.MainWindow will set the owner of the window to be its grandparent window, not parent window.
When the parent window makes (and shows) the child window, that is where you need to set the owner.
public partial class MainWindow : Window
{
private void openChild()
{
ChildWindow child = new ChildWindow ();
child.Owner = this; // "this" is the parent
child.ShowDialog();
}
}
Aditionally, if you don't want an extra taskbar for all the children... then
<Window x:Class="ChildWindow"
ShowInTaskbar="False" >
</Window>
Much of the reason for the MVVM pattern is so that your interaction logic can be unit tested. For this reason, you should never directly open a window from the ViewModel, or you'll have dialogs popping up in the middle of your unit tests.
Instead, you should raise an event that the View will handle and open a dialog for you. For example, see this article on Interaction Requests: https://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx#sec12
The problem seems to be related to Window.Owner, and indeed if you judge by previous knowledge that you might have of the Win32 API and WinForms, a missing owner would be the typical cause of such a problem, but as many have pointed out, in the case of WPF that's not it. Microsoft keeps changing things to keep things interesting.
In WPF you can have a dialog with a specific owner and you can still have the dialog appear in the taskbar. Because why not. And that's the default behavior. Because why not. Their rationale is that modal dialogs are not kosher anymore, so you should not be using them; you should be using modeless dialogs, which make sense to show as separate taskbar icons, and in any case the user can then decide whether they want to see different app windows as separate icons, or whether they want to see them grouped.
So, they are trying to enforce this policy with complete disregard to anyone who might want to go against their guidelines and create a modal dialog. So, they force you to explicitly state that you do not want a taskbar icon to appear for your dialog.
To fix this problem, do the following in the constructor of your view class:
ShowInTaskbar = false;
(This may happen right after InitializeComponent();
This is equivalent to Xcalibur37's answer, though the way I figure things, since WPF forces you to have both a .cs file and a .xaml file, you might as well put things that are unlikely to change in the .cs file.
Add "ShowInTaskbar" and set it to false.
Even if this post is a bit old, I hope it is OK that I post my solution.
All the above results are known to me and did not exactly yield the desired result.
I am doing it for the other googlers :)
Lets say f2 is your window that you want to display on top of f1 :
f2.Owner = Window.GetWindow(this);
f2.ShowDialog();
That's it , I promise it will not disappear !
HTH
Guy

How to access controls from MainWindow?

I have a text box in the MainWindow. I was wondering how I can access it from another window. I tried declaring an instance of the MainWindow but it doesn't work. Say I want to set the text in the MainWindow to something, in SecondWindow. How can I do that? Thanks!
Expose a public function on MainWindow that will allow you to set some property on it. Then when creating the new window pass an instance of MainWindow to its constructor. Now from within this new window call the public function you have exposed.

using routed events within Silverlight user controls

within my current project file I have a user control that has a storyboard animation applied to the control. When a button is clicked in the page the storyboard starts and basically visually presents the control to the user. The storyboard resides in the current page as a resource
<navigation:Page.Resources>
<Storyboard x:Name="PreferncesOpen">....</Storyboard x:Name="PreferncesOpen">
</navigation:Page.Resources>
Within the page I have button that I have a click event on that starts the storyboard
private void btnOpenPreferences_Click(object sender, RoutedEventArgs e)
{
preferencesPanel.Visibility = System.Windows.Visibility.Visible;
PreferncesOpen.Begin();
}
Within the userControl (preferencesPanel) I have a button that when clicked needs to close/collapse the user control. I plan to do this using Visibility.collapsed. I assume that I need to use routed commands since the button is within the user control but the actions need to be called within the page that contains the control? I'm still new to routed commands and I assume this is the correct approach. I'm just unsure how to click on a button within the user control and have it modify or execute commands that would impact how the page (in which this control resides) may change or for that part affect other elements within the page? For example when the button is clicked within the user control I would like the visibility of the user control to be set to collapsed. I also would like to have the width of one of the grid columns within the main page re-size. I have done this in the past using the code behind for the page but I am trying to separate some of this and I thought routed commands would be the way to go?
I'd greatly appreciate any tips.
Thank you in advance
The title is a bit misleading, you're asking about commands rather then routed events if I understand you correctly.
Here's an example of using a DelegateCommand<T> from the Prism library; It happens to be my personal preference.
Markup :
<Button x:Name="MyButton" Content="Btn" Command="{Binding DoSomethingCommand}"/>
Code-behind* or ViewModel :
(* if you're not using MVVM make sure to add MyButton.DataContext = this; so you're sure that the button can databind to your code behind effectively)
public DelegateCommand<object> DoSomethingCommand
{
get
{
if(mDoSomethingCommand == null)
mDoSomethingCommand = new DelegateCommand(DoSomething, canDoSomething);
return mDoSomethingCommand;
}
private DelegateCommand<object> mDoSomethingCommand;
// here's where the command is actually executed
void DoSomething(object o)
{}
// here's where the check is made whether the command can actually be executed
// insert your own condition here
bool canDoSomething(object o)
{ return true; }
// here's how you can force the command to check whether it can be executed
// typically a reaction for a PropertyChanged event or whatever you like
DoSomethingCommand.RaiseCanExecuteChanged();
The argument that's passed to the above function is the CommandParameter dependency property (in Prism it's an attached property as well as the Command property if memory serves me right).
When it's set, you can pass a value of your choosing to the command that you wish to execute.
Hope that helps.

WPF custom control question

i've done this before but i cannot find my old code.
how do you embed a window inside a window.
let say i created a custom form and saved it as Window1.xaml, and want to embed it in Window2.xaml, without copy and pasting the xaml code.. TIA
EDIT: i think my question is somewhat misleading, i'll rephrase it.
i have this Window1.xaml i added custom headers and background images/colors.
then in Window2.xaml, i want Window1 to be a custom control and embed it here.
not sure if its Content Presenters, still googling for the answer :)
You can't host a WPF Window inside another WPF Window, but you could move the content from one Window to another:
var window1 = new Window1();
var window2 = new Window2();
var content = window1.Content;
window1.Content = null;
window2.Content = content;
Note that you set window1.Content to null or else you get an exception, since the content will have a visual parent otherwise.
UPDATE
It appears all you need to do is to copy all the XAML between the <Window></Window> tags in Window1 into a new UserControl, then host that user control in Window2.
I believe you should make use of Pages or usercontrols in such cases. This way you can navigate to other parts/pages/controls defined in application. CodeKaizen is right , you can't host a window inside another window
I'm not sure you can do that - however, you shouldn't put the user interface directly into a window, use a normal control (either custom or user) instead and reuse that in your windows.
I know you can do it in code behind
//Window you want to show
Window1 child = new Window1();
object content = child.Content;
child.Content = null;
//Where to show
this.grid1.Children.Clear();
this.grid1.Children.Add((UIElement)content);
Hope helps!
It sounds like you really want a UserControl. Change Window1's type from Window to UserControl and then put that UserControl in Window2.

Resources