Reputation: 336
WPF Application:
I will have the identical
UI in two windows.
Let's say we have following win with identical fields: name,address,dob,phoneNo etc.
for adding
So is there a way so i can built
single UI
and use it on two different windows and write thelogic per window
.
I am kind of new to WPF and I have searched about it n find out Page used for navigation
on same window and UserControl for custom control as calendar etc. And i think this is not what i am looking for..
Trust me, there are lot of identical UI
in my application so i need to work around it..
So is it possible or is there another great way for this??
Or not possible and i have to copy and paste the xaml :( ??
Thank you.
Upvotes: 0
Views: 77
Reputation: 181
Here's a - hopefully - simple example of what you want, I think. I'm going to assume that while your UI is the same they are bound to different Models or ViewModels. I'll create my UserControl
first:
<UserControl x:Class="UserControlDemo.MyUserControl"
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:local="clr-namespace:UserControlDemo"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Loaded="UserControl_Loaded">
<Grid>
<TextBlock VerticalAlignment="Center" Width="200" Text="{Binding Path=objName}"/>
</Grid>
</UserControl>
It just contains a TextBlock
with a Binding
to something called objName
and notice that I'm using the Loaded
event.
The code-behind:
public partial class MyUserControl : UserControl
{
public string customObject
{
get { return (string)GetValue(customObjectProperty); }
set { SetValue(customObjectProperty, value); }
}
public static readonly DependencyProperty customObjectProperty =
DependencyProperty.Register("customObject", typeof(string), typeof(MyUserControl), null);
public string objName
{
get { return (string)GetValue(objNameProperty); }
set { SetValue(objNameProperty, value); }
}
public static readonly DependencyProperty objNameProperty =
DependencyProperty.Register("objName", typeof(string), typeof(MyUserControl), null);
public MyUserControl()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
var obj = CustomObjectFactory.GetCustomObject(customObject);
objName = obj.GetTypeName();
DataContext = this;
}
OK, let's see what we got here.I have two dependency properties,customObject
and objName
. The fact that they are dependecy properties provide functionality to bind them to controls in the UI. We bound objName to the Text
property of the TextBlock
in the UserControl above.
In the Loaded
event, I'm using a factory method to return the correct object type. See below.
The customObject
property, however, is set during the initialization of the control but to see that we have to go to out MainWindow.xaml (or the window where your UserControl will be used):
<Window x:Class="UserControlDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:UserControlDemo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl>
<TabItem Header="Tab 1">
<local:MyUserControl customObject="Object 1"/>
</TabItem>
<TabItem Header="Tab 2">
<local:MyUserControl customObject="Object 2"/>
</TabItem>
</TabControl>
</Grid>
</Window>
As you can see, the MainWindow.xaml doesn't hold very much "own" code just a Grid
, a TabControl
and two TabItem
s. In each of the TabItems there's a reference to the UserControl but notice that because we have a dependency property called customObject
in MyUserControl
I can pass a value to MyUserControl.
That value is then used together with a Factory
method and an Interface
to load two different types depending on which TabItem I'm in.
Below, I have created two classes; Object1
and Object2
which implements the ICustomObject
interface.
public class Object1 : ICustomObject
{
public string GetTypeName()
{
return this.GetType().ToString();
}
}
public class Object2 : ICustomObject
{
public string GetTypeName()
{
return this.GetType().ToString();
}
}
As you can see, these classes has one method which only returns the class name in a string.
To be able to dynamically return the correct object type depending on which window you're currently in we have to use a Factory method
.
public static class CustomObjectFactory
{
public static ICustomObject GetCustomObject(string ObjectName)
{
switch (ObjectName)
{
case "Object 1":
return new Object1();
case "Object 2":
return new Object2();
}
return null;
}
}
The result is that when I open Tab 1, I can see a TextBlock with the text "UserControlDemo.Object1" in it while in Tab 2 I see "UserControlDemo.Object2"
This means that I can add another TabItem and quite easily add another type to displa in my UI without altering my code very much.
I hope this was some help for you.
Upvotes: 0
Reputation: 1658
You can use MVVM design pattern. If you have two separate class object say Customer and Staff, but same name field/properties in object, you can use control's Binding Property to populate the fields and Windows's DataContext property to set the object as data source. There is one advantage also here that you don't need to write set/get values from controls. As binding property works both way, if object value changes, it will update on UI and if value manually modify by USer on UI, it will reflect in class object immediately.
Upvotes: 1
Reputation: 17213
If you want to share UI code between different pages or windows of your application, you need to create a UserControl
that contains the XAML and exposes configurable settings as DependancyProperty
's and actions as Event
's or Command
's.
Re. "I am kind of new to WPF": It's the same process as if you'd be doing this in WinForms, create a custom control that does what you want it to do and re-use it in multiple places.
Upvotes: 0