In a WPF (Silverlight) UserControl I have lots of custom control instances:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:My="clr-namespace:MyProject;assembly=MyAssembly" Name="uc1" >
...
<Grid x:Name="grid1">
...
<My:CustControl x:Name="name1" />
<My:CustControl x:Name="name2" />
<My:CustControl x:Name="name3" />
...
</Grid>
In MyProject I have not only the CustControl implemented, but also the CustControl1, the CustControl2, the CustControl3 and the like. Sometimes, I have to use another custom control type in the UserControl. Can I have only one place for changing custom control's name instead of changing it in all the numerous references in the XAML?
In other words, can I use an alias for those multiple custom control references inside my XAML and one place where I define the real CustomControl class' name for that alias?
Or maybe some other approach for solving this problem?
You could write a simple empty wrapper class, which would inherit the control you currently use. Then in XAML you would use this wrapper instead of the specific CustControl. At any time, you could change the base class for the wrapper at one single place.
But I must say: this design stinks. Are you sure you couldn't solve this issue with global styles/templates for one CustControl class?
Related
Okay, I understand what a UserControl is and how they can be shared across multiple Windows/Views to share functionality, etc. Though, what is the benefit of using a UserControl type? It seems a lot cleaner if you were to use the root control instead of wrapping it inside a UserControl.
Example:
<UserControl>
<Grid>
//...
<Grid/>
</UserControl>
vs.
<Grid>
//...
</Grid>
Using the root control also has the benefit if reducing the VisualTree.
UserControl has some properties it inherits from ContentControl, like ContentTemplate, ContentTemplateSelector, some other stuff. If you don't need those, you can create a user control, change the outermost element to Grid and change its base class to Grid in the .xaml.cs, and it'll compile. At least with the trivial example I just tried, it works fine.
However, unless you've identified some concrete problem being created by UserControl in your application, I can't see any reason to go to the trouble. But go ahead, if you like doing things that way.
What are the benefits and downsides of implementing a custom control in XAML by inheriting from UserControl:
<UserControl x:Class="MyButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button>
<!-- custom content here -->
<!-- custom behaviors in the code behind -->
</Button>
</UserControl>
vs inheriting from the control I'm putting inside the UserControl?
<Button x:Class="MyButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- custom content here -->
<!-- custom behaviors in the code behind -->
</Button>
There is no benefit to using a UserControl if you really want a Button. A UserControl just provides a simple way to create a control. From the UserControl Class page on MSDN:
If you do need to create a new control, the simplest way is to create a class that derives from UserControl. Before you do so, consider that your control will not support templates and therefore will not support complex customization. However, deriving from UserControl is a suitable model if you want to build your control by adding existing elements to it, similar to how you build an application, and if you do not need to support complex customization. (If you want to use templates with your control, derive from Control instead.)
As the remarks from MSDN note, using UserControl instead of Button as your base class will mean that your control cannot be templated, whereas when using a Button as the base class, you could still provide a new ControlTemplate.
You should always use the control that most closely suits your needs as the base class. The UserControl is only there to provide an easy way for us to add a collection of already existing controls to the UI. If that is not what you want to do, then don't use it.
I've a project made from the "WPF User Control Library" Template in Visual Studio.
This project contains one main usercontrol plus additional Windows/Usercontrols.
How can I "hide" these additional Windows/Usercontrols, so that the user can only import the main usercontrol from the assembly (I wanted to put a screen-shot to illustrate my question but unfortunately, my "reputation" is too low!).
Thx All
Fred
Make those controls internal. If you have classic UserControls with XAML and codebehind you will need to add x:ClassModifier="internal" to the root element in the XAML:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyNameSpace.MyUserControl"
x:ClassModifier="internal">
<!-- bla -->
</UserControl>
Maybe the usage of attributes will solve your problem. There is one attribute "DesignTimeVisible" inside the ComponentModel namespace. If you put such an attribute right above your class implementation and set it to false, the corresponding control should not be visible in the designers toolbox.
I believe that x:ClassModifier="internal" will make the entire user control internal. This may not be desirable.
Instead if you add x:FieldModifier="private" to those controls within the user control that you don't wish to be accessible to the UserControl consumer, the generated C# will have those controls as private. Note the use of lower case which is correct for a C# field modifier.
Usually, the WPF controls are declared in the .xaml files and not in the code behind (.xaml.cs files). However, sometimes I need to use some of those controls in code behind in order to manipulate them. How can I get the handle of such a control if it "resides" in the xaml file?
You can use the FindName() method of the ControlTemplate class.
// Finding the grid that is generated by the ControlTemplate of the Button
Grid gridInTemplate = (Grid)myButton1.Template.FindName("grid", myButton1);
I'm unsure about what you're asking, so I'll try and answer both instances that I'm interpreting as your question.
1)
If you want to declare an explicit control, and then edit it directly, all you have to do is set the name property like such:
<Canvas x:Name="myCanvas"/>
You can then access the canvas through the Name as such:
myCanvas.Background = Brushes.Blue;
2)
If you're looking to declare a generic control, and then use it multiple times, you can do it like this:
<Window>
<Window.Resources>
<Ellipse x:Key="myEllipse" Height="10" Width="10">
</Window.Resources>
</Window>
You can then access that predefined control using this syntax in code:
Ellipse tempEllipse = (Ellipse)FindResource("MyEllipse");
If you want to use the Resourse as a template for multiple controls, add x:Shared="false".
If you are creating a WPF window or a WPF page, you can bind commands to functions within the XAML.
<Page x:Class="WpfPageApplication.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfPageApplication="clr-namespace:WpfPageApplication"
Title="Page1" Background="LightGray"
>
<Page.CommandBindings>
<CommandBinding
Command="WpfPageApplication:PizzaCommands.ConfigurePizza"
Executed="OnConfigurePizza" />
</Page.CommandBindings>
There is another type of WPF form: a PageFunction. But it doesn't let you type:
<PageFunction.CommandBindings>
I can guess two possible explanations:
Because PageFunction is a generic object, you have to somehow enter the generic parameters into the XAML.
It's just an inconsistency in the framework.
Does anyone know how I can configure the CommandBindings for a PageFunction within the XAML? (I know I can do it in the code, but that's not the point).
PageFunction ultimately derives from Page, so I'm fairly certain you can just use <Page.CommandBindings> to define your command bindings. Certainly you can use <Page.Resources> in a PageFunction to define its resources.
Why can't you use <PageFunction.CommandBindings>? I don't know, but I think you're probably right when you say it has to do with the fact that PageFunction is a generic type. You'd need some way in XAML to say what the underlying type is. I think that's possible in the .NET 4.0 version of XAML but not in the current version.