WPF User Controls vs Custom Controls - c#

I am trying to creating a combobox with checkboxes on each line to allow multiple selecting. Would this be better as a User Control or Custom Control?
I haven't created a control before so just looking for a little advice on what direction I need to head.
Thanks.

UserControl (Composition)
Composes multiple existing controls into a reusable "group"
Consists of a XAML and a code behind file
Cannot be styled/templated
Derives from UserControl
CustomControl (Extending an existing control)
Extends an existing control with additional features
Consists of a code file and a default style in Themes/Generic.xaml
Can be styled/templated
The best approach to build a control library
In your case, I think UserControl would be better; here's an example for you:
<CheckBox Content="Property" IsChecked="{Binding Path=SomeProperty}" />
<ComboBox IsEnabled="{Binding Path=Enabled}" />

I would say use a datatemplate.
Like this: Looking for a WPF ComboBox with checkboxes
It's a lot more simple than trying to create your own control. :)

Related

How to access properties that are in an Inherited UserControl in C#?

I created an UserControl that consists of a TextBox and a Label controls. I created another UserContol that inherits the first, on which I added a Button. The difficult that I’m experiencing is that I can’t access directly from secondary UserControl properties like TextBox.Text that are in the primary UserControl. Is there a easy way to access properties from the primary UserControl or the only way is to create a public methods, like a “GetText()”, where I return the TextBox.Text property?
I assume you are talking about WPF.
Xaml view you can use x:FieldModifier="Public"
<Button x:Name="MyButton" x:FieldModifier="Public" />
Note that accessing inner controls is not best practise, your code should not care what controls view contains. If you want for example make button disabled create property in code behind and bind buttons IsEnabled to that property instead

WPF hide slider track

I'm using WPF (and the MVVM framework) to create an interface which has a slider on it.
<Slider Value="{Binding MotorDemandSpeed}" Maximum="3500" />
I'm trying to hide the track part on the slider so that you are left with just the 'thumb tack'. This is what the slider currently looks like (styles are controlled by a theme):
I've looked around at various methods, however I can't find a method that changes only a single slider.
Help is appreciated.
You need to set the Template property of this particular Slider instance to be able to override its ControlTemplate:
<Slider Value="{Binding MotorDemandSpeed}" Maximum="3500">
<Slider.Template>
<ControlTemplate TargetType="Slider">
<!-- define the custom template without a track here... -->
</ControlTemplate>
</Slider.Template>
</Slider>
In order to change the appearance of a control you will need to modify the control template. Each control is made up of many parts, and each part many objects. You can modify individual parts (such as the track) with the correct x:Key and TargetType.
This Question has an example of modifying a scrollbar control template, which is most likely similar to the template of this slider you have. The first step would be to identify the Xaml file in your theme which this slider uses and find the parts that define the trackbar, thumb, etc. From there you should be able to recreate the control to your liking, or just completely remove parts you do not need.
Are you using any third party controls that may have information on how to edit their themes? Perhaps try investigating Modifying Control Templates to get a better understanding of control templates.
Here is the MDSN page for the slider control template, you may find this useful.

Change inner user control in Silverlight/WPF by a property at design time

I am creating some custom user controls for WPF. This user controls contain custom dependency properties so I can fill them in the designer.
One of this properties is called "InnerUserControlType". This dependency proeprty is a custom enumeration containing some values like TextBox, ComboBox, Label, CheckBox, etc.
I would like to be able to set this property in my XAML pages in the designer and then see the user control change the displayed inner control depending on the property.
How should I implement this? The grid which will contain the inner control in my user control is a normal field, so it cannot be accessed from a static method property (like the dependency properties).
I want it to have it working in the designer so the designers can work easily.
Thanks a lot!
Put a ContentControl in the grid, bind the Content property to the UserControl via relative source
<ContentControl Content="{Binding RelativeSource={RelativeSource FindAnsector,
AncestorType={x:Tyle myNamespace:MyControl}}}"
and make a DataTemplateSelector that will check the value of InnerUserControlType and will return an appropriate data template containing the control that was asked for in the property.
Depending on your scenarios, you might need to make sure the controls in the data template have the right data context. If the data context of the controls should be the same as of the user control, then on the root element in the data template, add relative binding for data context. Something like (for the text box data template):
<TextBox DataContext="{Binding DataContext,
RelativeSource={RelativeSource FindAnsector,
AncestorType={x:Tyle myNamespace:MyControl}}}"
......
</TextBox>
EDIT:
I've noticed only the wpf tag and missed the silverlight one.
In Silverlight you don't have ...TemplateSelector properties, so use a converter instead.

SL Firing a Command from Within a ListItem Data Template, to a ViewModel for the MainPage.xaml

I may be making this more complicated than necessary ... but here goes.
I have my MainPage.xaml, in there I have references to two other UserControl's, ResultsView, and DetailsView.
Inside of the ResultsView, I have a ListBox bound to an ObservableCollection of custom items, I have a DataTemplate that is rendering each item. The item has a CaseID, and when I click on it, it's displayed as a HyperlinkButton, I need a Command I've set in the MainPageViewModel to fire, which handles changing the visibility to hide the ResultsView, and show the DetailsView.
How do I bind the Command of the Hyperlinkbutton to the Command located in my MainPageViewModel?
Thanks in advance!
edit for clarification:
MainPage.xaml
<resultsView:ResultsView/>
<detailsView:DetailsView/>
Each of the two views (ResultsView & DetailsView) have their own ViewModel. So I'm going from my DataTemplate which resides in a ListBox inside my ResultsView, I need to go up to the MainPageViewModel, an extra step than your answer mentioned. Tried your method naming my MainPage.xaml to Name="mainPage", and using that as the ElementName in my HyperlinkButton, but no luck. I'll do some research on the RelativeSource option and see if I can make that work.
Thanks for your help so far.
edit 2: Forgot to add that the DataTemplate is in a ResourceDictionary, not in the ResultsView.
Well, it depends on the specific details, not all of which you've told us, but I can give you some examples.
Let's say that your DataTemplate for the custom items resides in the XAML of the ResultsView user control. That's a good spot for it but you might have put it in a resource dictionary.
As you say, the ListBox is bound to the collection of custom items. Let's further assume that the custom items collection is itself a property in your MainPageViewModel. And you've said clearly that the command you want to bind to is also in MainPageViewModel.
So the problem, which is a very common one, is that you are working inside a template associated with a binding to a collection, and so your DataContext is a custom item. It is no longer the main view-model itself. That's great as you show appropriate properties of the custom item like CaseID. But it's not great when you want to escape to the top-level of view-model.
If what I've said is true, then the ResultsView user control is in fact probably bound to the MainPageViewModel because you haven't "drilled into" the custom items collection yet. So, what you need to do is find a way using the binding syntax to reference the ResultsView user control from inside the DataTemplate for the ListBox. If you can do that, then you've escaped the collection.
There are two main approaches to do this:
ElementName syntax
RelativeSource syntax
I'll describe ElementName syntax and you can look up the other one.
Part 1) Name your ResultsView UserControl element like this:
<UserControl ....
Name="resultsView">
<!-- ... -->
Part 2) Inside your DataTemplate where you are defining the appearance of the hyperlink use the ElementName syntax to refer to that element:
<TextBlock>
<Hyperlink Command="{Binding DataContext.ItemDetailsCommand, ElementName=resultsView}"/>
</TextBlock>
So first we use ElementName to get the ResultsView UserControl element, and then we have a path with two pieces: the first piece is the DataContext property of the ResultsView which gives us the MainPageViewModel (yeah!), and then the property of the command we want to invoke.
That's one way to "escape" the binding and issue commands found at a higher level in the view-model.

WPF: How To Customize Generic Custom Window?

This is a tough question, but I'll try to explain anyway...
I have a custom control window that is used all over my applicaton. The reason I did this is because I wanted the various windows and dialog boxes to be fully customizable across my program. I.e., the minimize, maximize, close button and frame are all custom. This window is templated inside my generic.xaml. Now this works and it's all good. The idea I got was from http://www.codeproject.com/KB/WPF/CustomFrames.aspx
Now the users of this custom window are user controls in their xaml they basically use MyWindow as their root element:
<MyWindow>
....
</MyWindow>
But now what I'm trying to do is "inject" certain elements into MyWindow from the User Control's xaml. MyWindow would simply have a container for hosting them. For example, they might want to inject a toolbar button that appears right next to the minimize button. So for example, I might have a user control that does the following (where MyWindow is the root element):
<MyWindow>
<MyWindow.ToolBar>
<Button x:Name="BlaBla"/>
</MyWindow.ToolBar>
</MyWindow>
This would put "blabla" right next to the minimize button for example. But I'm wondering if it's even possible to do this. I.e., the whole MyWindow.ToolBar thing. Is there a construct for this, is this an attached property or something weirder?
It definitely is possible, depends on your choice of types for the DependencyProperty. You could use IEnumerable and bind the MyWindow.ToolBar dp to the ItemsSource on your internal ToolBar.
<ControlTemplate>
<!-- ... snipped down to the ToolBar ... -->
<ToolBarTray>
<ToolBar x:Name="PART_ToolBar" />
</ToolBarTray>
</ControlTemplate>
With the appropriate code in OnApplyTemplate to pull PART_ToolBar and create new Binding for the ItemsSource.
EDIT: rereading your question it appears that I missed that you wanted to add this elsewhere. My suggestion then would be to use this as an object dependency property, with a ContentPresenter bound to the MyWindow.ToolBar with a Visibility set if the binding is not {x:Null}.

Categories

Resources