I created WPF UserControl which enables to enter some information now I have Main entry form where I want to use tow instances of that UserControl When I add my YserControl as Resource and than try to use it as ContrntControl's Content exception is thrown informing that control is already a logical child. Can anyone provide with sollution?
You can use the x:Shared attribute so that whenever something references the resource, a new instance is created instead of it being shared.
Thus you might have something like this:
<Window.Resources>
<MyUserControl x:Key="MyControlKey" x:Shared="False" .... />
....
</Window.Resources>
http://msdn.microsoft.com/en-us/library/aa970778.aspx
http://www.wpfmentor.com/2009/01/how-to-ensure-new-instance-of-resource.html
I just found out way to not throw exception but I want to know if this is right sollution
<TaicoControl:WizardPage Title="Title1"
BackButtonVisibility="Collapsed"
CancelButtonVisibility="Collapsed"
Description="Desctiption1"
PageType="Interior">
<ContentPresenter ContentTemplate="{StaticResource PersonEntryFormTemplate}" DataContext="{Binding Person}" />
</TaicoControl:WizardPage>
<TaicoControl:WizardPage Title="Title2"
BackButtonVisibility="Collapsed"
CancelButtonVisibility="Collapsed"
Description="Description2"
NextButtonVisibility="Collapsed"
PageType="Interior">
<ContentPresenter ContentTemplate="{StaticResource PersonEntryFormTemplate}" DataContext="{Binding Person.ContactPerson}" />
</TaicoControl:WizardPage>
Related
I Create a user control in "MyControl.xaml" like this:
<TreeView x:name="treeView" Grid.Row="0"/>
<!-- Rest of doc -->
and the user control get hosted in MainWindow.xaml:
...
...
Now how can I access the object treeView in the xaml behind code in MainWindow.xaml.cs?
I Tried this but failed.
MyControl.treeView.Items.Add(item); // object item created somewhere.
I Got the Error:
Error 1 An object reference is required for the non-static field, method, or property 'MyNameSpace.MyControl.treeView
What am I supposed to do about this?
I have created a Usercontrol with name "UC" as below
<Grid>
<StackPanel>
<TextBlock>Child</TextBlock>
<TreeView x:Name="treeView"/>
</StackPanel>
</Grid>
Added the control to its host
<Grid>
<local:UC x:Name="MyUC" />
</Grid>
And in code behind I can access it like...
MyUC.treeView.Items.Add("Item");
Please check your implementation
sorry if this question is overly simple, but I'm having a hard time figuring out how to create backgrounds to controls - in the hopes that it will improve app performance.
I have 9 different controls. All of them have a background. The backgrounds are made up of either images, other controls or both. All of those backgrounds have another background.
Think of this like Power Point with slides, slide layouts and slide masters - inherited in that order. I have 9 slides / controls.
The first 3 controls have the same "control layout" (let's call it
ControlLayout1). ControlLayout1 gets some of it's elements from ControlMaster1.
The second 3 controls also have the same control layout, but it is
different from the first. Let's call it ControlLayout2. It also
inherits from ControlMaster1.
The final set of 3 controls are different again. We can call them
ControlLayout3. But this time, they inherit from a different master - ControlMaster2.
Right now in each control I'm writing out all the XAML each time separately. I'm thinking there must be a way to not write these in each of these each item. Ideally, what I would like to create is one set of XAML that can be reused.
Here's some pseudo-XAML:
<UserControl x:Name="Control1">
<MyBackground (ControlLayout1)/>
</UserControl>
<UserControl x:Name="Control2">
<MyBackground (ControlLayout2)/>
</UserControl>
<UserControl x:Name="Control3">
<MyBackground (ControlLayout3)/>
</UserControl>
And then somewhere for ControlLayouts (I don't know, like Application.Resources or elsewhere)
<Canvas x:Name="ControlLayout1">
<MyMasterBackground (ControlMaster1)/>
</Canvas>
<Canvas x:Name="ControlLayout2">
<MyMasterBackground (ControlMaster1)/>
<TextBox Text="The Control 2">
</Canvas>
<Canvas x:Name="ControlLayout3">
<MyMasterBackground (ControlMaster2)/>
<TextBox Text="The Control 3">
</Canvas>
And then for the ControlMasters
<Canvas x:Name="ControlMaster1">
<Canvas.Background>
<ImageBrush ImageSource="/Images/image1.jpg" />
</Canvas.Background>
</Canvas>
<Canvas x:Name="ControlMaster2">
<Canvas.Background>
<ImageBrush ImageSource="/Images/image2.jpg" />
</Canvas.Background>
<TextBox Text="Control Master 1">
</Canvas>
Once defined, the ControlLayouts and ControlMasters never need to change - they are static.
Beyond just having a smaller XAP if I can put these all in one location and reuse the XAML, I'm hoping performance will be improved in my app as the ControlLayouts automatically get BitmapCached or something like that.
So first, is there a good strategy to implement the above (the ControlLayouts and Masters do not have any code-behind)? Secondly will performance be improved in loading of Control1, Control2, etc.? Finally, if they were pure usercontrols (i.e. they had some code behind), would that be better for performance?
Thanks in advance!
What you ask for is a combination of a few things:
About the Background thing: just create a dependency property (let's call it MyBackgroundDP) of type Brush in the code behind of a UserControl, and bind it to your XAML like:
<UserControl ...>
<Grid Background={"Binding MyBackgroundDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}">
<!-- More XAML declarations -->
</Grid>
</UserControl>
To create the dependency property, you can use the built in snippet in visual studio: propdp
Simply write "propdp" and that TAB twice. Fill up the fields and it's all good.
Alright so that was easy enough, right? ;)
Now the tougher part: making so-called master pages.
Actually it's not that much different from the background thing.
Declare another dependency property, only this time of type object, or FrameworkElement (better).
Then in your XAML, you declare a kind of placeholder: ContentControl. Let's call it MyContentDP for this example:
<UserControl ...>
<Grid Background={"Binding MyBackgroundDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}">
<ContentControl ContentTemplate="{Binding MyContentDP, RelativeSource={RelativeSource Mode=FindAncestor, AncestoryType=UserControl}}" />
</Grid>
</UserControl>
You can then fine tune whatever else you want to provide in this "master view", add a border around the Grid, put some flowers, you name it.
Once you're done, this is how you use it, assuming it was called MyUserControl
<Window ...
xmlns:local="...reference_to_your_usercontrol_dll/exe">
<Grid>
<local:MyUserControl MyBackgroundDP="Red">
<local:MyUserControl.MyContentDP>
<!-- More XAML declarations here -->
</local:MyUserControl.MyContentDP>
</local:MyUserControl>
</Grid>
</Window>
Now the performance point:
If you put all the XAML for this as a Custom control (which is DIFFERENT from a UserControl), you can then put all the XAML in your App.xaml
Why? because parsing XAML can be an intensive operation, and if you make WP7/SL parse it at runtime whenever you need it, you lose performance.
Instead, your App.xaml gets parsed at startup, then it's in memory. That's what's done in the loading of your application. You would get a performance boost, although it would be minimal for controls made of few XAML, it is still a good practice.
Hope this helps,
Bab.
I created a control which is hosting two content controls. I would like Caliburn to
resolve the View/ViewModel for me but Caliburn ignores the hosted/inner ContentControls with the name SignalGenerator (see below). Any idea how to get around that problem?
<cc:HorizontalSplitterLayoutControl >
<cc:HorizontalSplitterLayoutControl.UpperContent>
<Label Content="Blockdiagram" />
</cc:HorizontalSplitterLayoutControl.UpperContent>
<cc:HorizontalSplitterLayoutControl.LowerContent>
<ContentControl x:Name="SignalGenerator"/>
</cc:HorizontalSplitterLayoutControl.LowerContent>
</cc:HorizontalSplitterLayoutControl>
I haven't tried myself, but you should be able to do something like the following:
<ContentControl x:Name="SignalGenerator" cal:View.Model="{Binding}" />
In another project I had to do it like this:
<ContentControl cal:View.Model="{Binding SignalGenerator}" />
I´m learning the MVVM for WPF. I know how to rout events and split the Code in View, ViewModel, Model. I have in my main-XAML a TabControl and have split the tabs into different views.
My Question is, how can i pass an object from one class to another? (From the MainWindow.cs to the SubWindow.cs)
MainWindowRessources XAML:
....
<DataTemplate DataType="{x:Type vm:SubWindow}">
<vw:SubWindow />
</DataTemplate>
<vm:SubWindow x:Key="subView" />
..
MainWindow XAML:
<Window.Resources>
<ResourceDictionary Source="MainWindowResources.xaml" />
</Window.Resources>
...
..
<TabItem>
<ContentControl Content="{StaticResource subView}" />
</TabItem>
...
..
You should consider implementing the mediator pattern to allow your view models to communicate with each other.
See this Stackoverflow answer for more information.
Depending on the context/use, you could create a DependencyProperty on the SubWindow class, and pass the object as a parameter, ala <vm:SubWindow MyNewProperty="some-value-or-object here"/>.
Info about creating DependencyProperties: http://msdn.microsoft.com/en-us/library/ms752914.aspx
What is the object you're wanting to pass?
I have the following code and basically what i am not able to figure out is how to clone the whole grid and make a blank copy of them side by side.... for a clear understanding this is something to do with hospital application and the grid is related to a pregnancy so when said 'ADD CHILD' button a whole new grid should be created during run time, thanks for the help below is a link that might help people cause i tried it but not sure how to display it
How can you clone a WPF object?
You should put the object you are want to "clone" in a DataTemplate and reference this template from an ItemsControl, then when you need another grid add another item to the items control (or even better to the list the control is bound to) and the ItemsControl will create a new grid and bind it the new object.
For an example take a look at this post on my blog.
Here is an example for this application (I left only the relevant parts and I didn't test it, so there are probably some typos there):
<Window ... >
<Window.Resources>
<DataTemplate x:Key="ChildTemplate">
<Grid>
...
<TextBlock Text="Delivery Date:" Grid.Column="0" Grid.Row="0"/>
<TextBox Text="{Binding DeliveryDate}" Grid.Column="1" Grid.Row="0"/>
<TextBlock Text="Delivery Time:" Grid.Column="0" Grid.Row="1"/>
<TextBox Text="{Binding DeliveryTime}" Grid.Column="1" Grid.Row="1"/>
...
</Grid>
</DataTemplate>
</Window.Resources>
...
<Button Content="AddChild" Click="AddChildClick"/>
...
<ScrollViewer>
<ItemsControl ItemsSource="{Binding AllChildren}" ItemsTemplate="{StaticResource ChildTemplate}">
<ItemsControl.PanelTemplate>
<ItemsPanelTemplate><StackPanel Orientation="Horizontal"/></ItemPanelTemplate>
<ItemsControl.PanelTemplate>
</ScrollViewer>
...
</Window>
And in cs:
Set an object with all the form data as the Window's DataContext. I'll call this class PostDelveryData.
Create another class with the repeating data. I'll call it ChildDeliveryData.
Add a property of type ObservableCollection<ChildDeliveryData> called AllChildren to PostDeliveryData; it's important it'll be ObservableCollection and not any other type of collection.
Now, for the magic:
private void AddChildClick(object sender, RoutedEvetnArgs e)
{
((PostDeliveryData)DataContext).AllChildren.Add(new ChildDeliveryData());
}
And when you add the new item to the list another copy of the entire data template will be added.
I'm not sure that you're using the correct approach here. I would approach the problem by creating a "ChildGridControl" with a Child property, and let the Child property handle the databinding. Adding a new child to the GUI would involve creating a new instance of the ChildGridControl.
If I am understanding correctly, you should create a UserControl, which wraps your Grid and subsequent controls inside. And use this User control anywhere you wanted to replicate that UI.