How to access Main Form Public Property WPF - c#

I have a user control from where I have to call the property of the window which contain the user control how can I access that property.
Suppose I have Title Property in my window and I want to access Title property of the window from the user control. Any idea
is That OK
(App.Current.MainWindow as MainWindow).Title;
Thanks in advance

This code will get the parent window where the user control resides:
FrameworkElement parent = (FrameworkElement)this.Parent;
while (true)
{
if (parent == null)
break;
if (parent is Page)
{
//Do your stuff here. MessageBox is for demo only
MessageBox.Show(((Window)parent).Title);
break;
}
parent = (FrameworkElement)parent.Parent;
}

Why dont you bind title property of parent window with your control's property?
Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window Title" Height="500" Width="650" ResizeMode="NoResize" x:Name="us1">
TextBox Name="txtBlk" Text="{Binding Path=Title, ElementName=us1}"/>
/Window>

Related

C# WPF better way to iterate on children and change property

I have to iterate through all children of a stackPanel.
Being new to WPF I do that
foreach (var item in spTab3.Children)
{
if (item.GetType() == typeof(ListBox))
((ListBox)item).Visibility = Visibility.Collapsed;
if (item.GetType() == typeof(Grid))
((Grid)item).Visibility = Visibility.Collapsed;
....
}
that is I have to cast all types of elements to get to set the visibility. I bet there is a smarter way to do all the togheter.
Thanks
---EDIT---
So in short I have a stackpanel spTab3 with children.
When I do what suggested by Bijington:
spTab3.Visibility = Visibility.Collapsed;<----------set all children to collapsed
spTab3.Children[iVisibleTab-1].Visibility = Visibility.Visible;<----set only one to visible
the second line has no effect.
While when I do as stated by Spawn that works:
foreach (var item in spTab3.Children)
((UIElement)item).Visibility = Visibility.Collapsed;
spTab3.Children[iVisibleTab-1].Visibility = Visibility.Visible;
can anyone explain me why?!?
Every child in Panel is UIElement. So its type derived from DependencyObject which has SetValue method. Use it.
foreach (UIElement item in spTab3.Children)
{
item.SetValue(UIElement.VisibilityProperty, Visibility.Collapsed (or Visible));
}
Keep in mind that it's not a WPF style solution. You better need to declare dependency property and to bind item's visibility to this property.
In case that panel and code are inside a Window
public static readonly DependencyProperty IsItemVisibleProperty = DependencyProperty.Register("IsItemVisible", typeof(Visibility), typeof(MainWindow), new FrameworkPropertyMetadata(Visibility.Visible));
public Visibility IsItemVisible
{
get
{
return (Visibility)GetValue(IsItemVisibleProperty);
}
set
{
SetValue(IsItemVisibleProperty, value);
}
}
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Visibility="{Binding IsItemVisible,RelativeSource={RelativeSource AncestorType=Window}}">Collapsed 1</Button>
<Button Visibility="{Binding IsItemVisible,RelativeSource={RelativeSource AncestorType=Window}}">Collapsed 2</Button>
<Button>Visible</Button>
</StackPanel>
</Window>
A more efficient way of showing/hiding the Children within the StackPanel would be to simply set the Visibility property on the StackPanel itself.

WPF: Popout existing usercontrol

Imagine next situation: I do have application window with several usercontrols inside. They was displayed side by side in past, but now I want to show one of them in popup window. Not in Popup control but new Window.
See example XAML:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication3="clr-namespace:WpfApplication3"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<wpfApplication3:UserControl1 Visibility="Hidden"
x:Name="UserControl1"/>
<Button Click="ButtonBase_OnClick"
Width="100"
Height="60">open window</Button>
</Grid>
In code behind I need to deattach usercontrol from current Window and assign to new one:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var parent = VisualTreeHelper.GetParent(UserControl1);
if (parent != null)
{
parent.RemoveChild(UserControl1);
}
var w = new Window
{
Content = UserControl1,
Title = "sample",
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.CanResize
};
w.Show();
}
And after calling w.Show() I always getting blank white window.
If in button click handler change
Content = UserControl1
to
Content = new UserControl1()
I will get right content as well.
But I can't use this way because I want to keep my usercontrol state during pop-out and pop-in events.
So how can I show in new window existing usercontrol without recreating it?
I am not sure how you are calling RemoveChild on a DependencyObject as that method doesn't seem to exist. Note that VisualTreeHelper.GetParent returns a DependencyObject so, the code you posted should not compile unless you have an Extension method somewhere defining RemoveChild.
In your case what you want to do is cast your parent object to type Grid or Panel and then remove the UserControl from the Children property, then set your UserControl as the Content of your window.
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Grid parent = VisualTreeHelper.GetParent(UserControl1) as Grid;
if (parent != null)
{
parent.Children.Remove(UserControl1);
}
var w = new Window
{
Content = UserControl1,
Title = "sample",
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.CanResize
};
w.Show();
}
There was a similar question asked here
that gives a very detailed answer.
The quick answer is that you will have to remove the control from the main window and then add it to the popup window.

Code behind Data Context is null, even though its values are showing on the page - Windows Phone 8.1 [duplicate]

This question already has answers here:
WPF User Control's DataContext is Null
(3 answers)
Closed 7 years ago.
I have a Page which contains a User Control, the Page's Data Context is bound, and so is the Contained User Control. When the Page is displayed, I can see that the User Control in the Page is displaying the values from the element as I would expect, such as Title and Description, however, in the Code Behind on the same User Control, the Data Context is null.. What am I doing wrong?
I need the Data Context so I could edit it's values within the control or change other UI elements within the page. What am I doing wrong here?
MyPage:
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
DataContext="{Binding}"
The use of the User Control with that page:
<Grid Grid.Row="1" x:Name="ContentRoot" Margin="19,9.5,19,0">
<local:ucFooControl DataContext="{Binding}"/>
</Grid>
Then, where I am seeing null in User Control Code Behind, even though display elements are showing bound items.
public ucFooControl()
{
this.InitializeComponent();
if (this.DataContext != null)
{
bar= (Bar)DataContext;
this.DoSomething((bar);
}
}
Try this:
public MyUserControl1()
{
this.InitializeComponent();
DataContextChanged += OnDataContextChanged;
}
private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
if (this.DataContext != null)
{
bar = (Bar)DataContext;
this.DoSomething((bar);
}
}

My inputcommand keybinding to main window does not work when child window is focussed(same wpf window)?

I am facing one problem with input command key binding.
Here i explain my situation...
I have binded the input command key binding like below,
<Window x:Class="DefaultBehavior_KeyBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.InputBindings>
<KeyBinding Key="F2" Command="{Binding TestCommand}"/>
</Window.InputBindings>
<Grid>
<Button Content="Add" Width="100" Height="35" Grid.Row="0" Name="EmptyButton" Click="EmptyButton_Click"/>
</Grid>
It works fine. Then i opened the new wpf child window in button click event like below,
public partial class MainWindow : Window
{
public ICommand TestCommand { get; private set; }
public MainWindow()
{
this.TestCommand = ........some command is attached here...
InitializeComponent();
this.DataContext = this;
}
private void EmptyTabButton_Click(object sender, RoutedEventArgs e)
{
Window childwindow = new Window() { Title = "ChildWindow", Width = 200, Height = 300 };
childwindow.Show();
}
}
After opening the child window, the key binding to main window not working when child window is focused. If i switch the focus to main window means, it fine.
I know, both the main window and child window are independent to each other.
But my question is, how can i make it as work my child window is focussed when i binded the keybinding to main window only. i don't want to set this binding to each child window because in my case i am using lot of child windows.
Any one please provide your suggestion to me?
The key bindings will only work if the Form is focused.
You could redirect every Command in your new Window to the Main Window
Change your Constructor to of the new Window to accept a Main Window and save this window:
MainWindow mainWindow;
public Window(MainWindow w)
{
mainWindow = w;
}
Whenever a Keybinding executes just do something like this:
mainWindow.TabPress();
And show the Window with
Window childwindow = new Window(this) { Title = "ChildWindow", Width = 200, Height = 300 };
childwindow.Show();
Can you try setting the Input Bindings in Window style (that should defined in App.xaml), so that it will apply to all Window objects.
This code is NOT TESTED! (but it should work anyways :D)
You could add the InputBindings from the MainWindow to the childwindows InputBindingCollection as follows:
private void EmptyTabButton_Click(object sender, RoutedEventArgs e)
{
Window childwindow = new Window() { Title = "ChildWindow", Width = 200, Height = 300 };
childWindow.InputBindings.AddRange(this.InputBindings);
childwindow.Show();
}
By doing so, the childwindow should react to your input and execute the commands from the MainWindow.

Assign tab content in WPF to a page

I am trying to add dynamic tabs to my application. Right now if I click a button, it will open a new page. What I want is to open this page in a new tab. But when I set up the tab content to a page , the code complains. I wanna do something like this
private void bttnGoToClientsOnClick(object sender, RoutedEventArgs e)
{
var content = new TextBlock();
TabItem tab = new TabItem();
tab.Header = "Search Page";
SearchPage sp = new SearchPage();
tab.Content = sp;
tabControl.Items.Add(tab);
this.NavigationService.Navigate(sp);
}
is there any way I can convert my page to usercontrol or cast it as user control
Thank you!
But when I set up the tab content to a page , the code complains.
It wouldn't hurt if you were more specific here :)
What is SearchPage class? It doesn't seem to be the part of the WPF framework. I googled it up on the
http://www.intersoftpt.com/ website. Is that it?
TabItem.Content needs to be of ContentControl type, which SearchPage - apparently - is not. I'm sure you need to embed this SearchPage object in some control presenter, such as a panel, before you can assign it to TabItem.Content.
Update:
Try this, then:
TabItem tab = new TabItem();
tab.Header = "Search Page";
SearchPage sp = new SearchPage();
this.NavigationService.Navigate(sp);
// ----------------------------------------------------
var frame = new Frame(); // !
frame.Navigate(sp); // !
tab.Content = frame; // !
// ----------------------------------------------------
tabControl.Items.Add(tab);
While I believe this should work, I haven't tested it. Please let me know if it doesn't do the trick.
You can always create your own UserControls, directly in the XAML definition (even if they are partial pages or windows).
In this example I assume that your SearchClass is defined in the [YourProject].Model namespace (where [YourProject] is the name of your project)
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:search="clr-namespace:[YourProject].Model">
<search:SearchClass>
<!--<Grid>
...ANYTHING YOU WANT HERE ! ...
</Grid>-->
</search:SearchClass>
</UserControl>
Now you can create an instance of the UserControl, even in XAML or in code-behind (remember only to declare the namespaces correctly!):
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:ctrls="clr-namespace:WpfApplication1"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<UserControl1 />
</Grid>
</Window>
...and this my code-behind...
UserControl1 myControl = new UserControl1();

Categories

Resources