Is there a list somewhere? I spent a lot of time yesterday trying to bind an ObservableCollection<string> to a RichTextBox, then when that didn't work to a FlowDocument (which I eventually found a simple work-around for). If there isn't a list is there some intellisense trick to find out? I found it really strange that FlowDocument didn't support data binding to a collection. It has a DataContext property that shows up in Intellisense so I figured there was some way to bind a collection. That coupled with the fact that supports single item binding made me certain I just couldn't find the proper property. Does everyone just eventually figure this out the hard way or did I miss something obvious?
[Edit - and the italicized text above are edits]
I guess I'm such a beginner I don't even know how to ask the question properly. I have half my answer. What I really want to know, I now realize is two things.
how do I tell which controls can be bound to a collection (the answer from below is any control that has an ItemsSource property)
When looking at a control how do I know which of the properties are dependency properties that I can bind data to? (I do realize - just now - that when I go to browser and look at each property the summary section is mentioning which properties are dependency properties. A little laborious to click on every property in a control but I can live with that if that's the easiest way to find out).
Anything that is derived from FrameworkElement (which is every WPF control to my knowledge) supports data binding. However binding a collection requires a special type of binding. You will need to bind to a ItemsControl or use a control that has the ItemsSource DependencyProperty
All WPF controls support DataBinding, on almost every property. If you post specific examples, we'll be better able to help you.
Data binding is supported on any DependencyProperty.
The target property must be a dependency property. Most UIElement properties are dependency properties and most dependency properties, except read-only ones, support data binding by default. (Only DependencyObject types can define dependency properties and all UIElements derive from DependencyObject.)
In the case of a RichTextbox or FlowDocument you can achieve binding thru the Run.Text dependency property as of .Net 4.0. But keep in mind in a RichTextBox:
Binding text to a Run object contained within RichTextBox is not supported. Editing operations within the RichTextBox may cause the binding to be cleared.
You can bind the Document property as well, however, this may require some additional logic if you need the textual data contained within.
Related
I have often bemoaned the fact that the WPF ToggleButton does not have properties for AlternateContent and AlternateContentForeground. I'm curious if there's any advantage to creating a DependencyObject with attached properties, or deriving a custom control from ToggleButton?
My assumption is that attached properties are advantageous if they are useable on more than one control. So in my case I'm leaning towards a derived control since those properties are unique to the togglebutton.
AttachedProperties are useful in a couple scenarios:
You want to use them as attached behaviors on things that interact with another Control, like Grid.Row
You want to add properties to a control but you don't want to force clients that get that behavior to be derived from your specific type. E.g. if you had a behavior that you wanted on Buttons rather than ToggleButton, then you may want to go with that approach so you could get that new property on ToggleButton and RadioButton, rather than forcing someone to derive from MyCoolButton.
For what you're describing just subclassing ToggleButton seems to make sense.
Actually, this kind of styling should be done with a trigger, or using the VisualStateManager.
Well I'm designing a Custom WPF control - fore the sake of learning - that display logs message in a similar way Visual Studio does. I want to allow the user add messages by adding message istances to an Items collection, or by binding to an ItemSource. I think this is a well established pattern in many wpf controls, but I have no Idea on how achieve it. I know I can obtain the same result by adding a listview as a part of my control, but the project goal is learning, so I prefer avoid that solution. Any idea ?
Have a read around the ItemsControl, your custom control can inherit from an ItemsControl, or a derivative of it. If you create an ObservableCollection containing your items and bind that to your ItemsSource, then your list will be automatically updated. You can style the ItemTemplate and Template to give the list a different look and feel.
There's loads of info here
I am trying to hook up an ICommand on the model to a button within the ItemTemplate of a Pivot control.
To get a link to the parent model from within the ItemTemplate I usually use ElementName specifying the Name I provided for the xaml page.
This works when I use a ListBox to contain the items but not a pivot control.
Does any one have any ideas or come across this problem before?
Just noticed that if I define the PivotItems in xaml the Binding works. So it is only failing when I am dynamically populating the Pivot control.
UPDATE : OK So I'm beat with this now. I have linked the event to the models ICommand in the views code behind (nasty) and I'm going to look # this later. I will post my solution here once I have found it but any help would be great.
This is a know problem in Silverlight 3. Since, WP7 uses it right now, you will face the same thing with it as well.
To fix that, wrap your DataTemplate content that you put in your ItemTemplate into a UserControl.
Look into this question for further details.
WP7: Why does a ListBox.ItemsPanel break my ElementName data binding?
I have started writing some custom controls for a highly visual project. I was wondering what are your 'best practices' when coding WPF custom controls?
If you want your custom control to support direct content like this:
<CustomObject>
Direct content example 1
</CustomObject>
<!-- or -->
<CustomObject>
<Button Content="Direct content example 2" />
</CustomObject>
Then you need to use the ContentPropertyAttribute which tells WPF which property is actually being set when you write xaml like this.
The attribute can be used like this:
[ContentProperty("NameOfProperty")]
public class CustomObject
{
[...]
ContentControl uses this attribute to set the Content property but note that the property can be called anything; the WPF TextBox, for example uses this attribute to set the Text property.
E.G.
[ContentProperty("Text")]
The property also does not have to be a dependency property (see the MSDN documentation example for evidence of this).
Finally, this attribute is specific to the xaml parser and not to ContentControl and can be used with any type which can be seen from the TextBox example above (TextBox does not derive from ContentControl).
Keep property names the same as the property names for built-in Controls if you can do so without changing their meaning.
e.g. if you have a CustomerDisplayer custom control don't call the list of customers Customers, call it ItemsSource.
It might seem counter intuitive at first but it saves a lot of headache in the long run because future programmers can make a lot of assumptions about how a property called ItemsSource will act that they can't necessarily make about a Customers property.
Make sure the control can be re-styled and re-templated without changing the way the control operates. Don't make the control assume that the Listbox and Button are both within the same panel or that there even is a Listbox or Button. Check out the MSDN article on control authoring for some recommendations on how to do this.
Some content controls are dependant on the existence of other controls in their ControlTemplate. Typically this should be documented using the TemplatePart attribute.
The Combobox control, for example, is dependant on the existence of a TextBox and a Popup controls in its template.
This would be documented by placing the attribute on the class like so:
[TemplatePart(name="PART_EditableTextBox", type=typeof(TextBox))]
[TemplatePart(name="PART_Popup", type=typeof(Popup))]
public class Combobox : Selector
{
[...]
The naming convention is "PART_controlIdentifier".
The relevant items would then be given the same names in the control template so that they can be located in the OnApplyTemplate method.
This then allows the control to hook up to events, set properties and call methods on the controls contained in the template.
This attribute is for documentation purposes so that people designing custom control templates (and tools such as Expression Blend) know that the control is dependant on the existence of another.
Learn how to use both dependency properties and routed events (and how they work) so that you can use them effectively in your own control.
Both of these types provide services for integrating your control with the systems built into WPF.
By using these two features in your custom controls you will get the following advantages:
Dependency Properties provide support for databinding, animations and can be used in styles.
Routed Events can be propogated through the visual tree which means that other elements can handle the events.
What is considered the best way of enabling or disabling multiple controls in Silverlight at the same time (textbox, combobox, autocompletebox and the like)?
I suppose I could bind the "IsEnabled" property of each control to a boolean property. That property only exists for interactive controls and not textblocks.
I could loop through the children recursively and set their properties appropriately, but that seems inelegant.
Ideally, I'd like to just set some disable-like property on the parent container of the controls, giving even the TextBlocks a disabled look similar to a Windows form.
Is there a way to just disable the parent container?
Use the ContentControl Silverlight provides.
<ContentControl x:Name="GroupOfControls" >...Your controls...</ContentControl>
//Enable and Disable
GroupOfControls.IsEnabled = false;
You could use a ViewModel approach similar to the answer in StackOverflow 1545844
By having a calculated IsEnabled property you can then bind the elements in the View which should be controled by this property.
Usually I always create a ControlHandler Class that does all the updates on my controls. (Just to separate concerns)
Recently we had to reset all controls on the form and didn't want to loop through every single control.
All control-related data logic gets updated in the ControlHandler class.
We then only apply the values appropriate values / properties onto our controls.
This is a workaround but worked pretty well and also cleanly for us.
There are, of course, better ways to solve that..
I was looking into disabling multiple controls when fetching data from a web service.
The BusyIndicator control got me what I needed with very little effort.
Maybe it'll be a good enough solution for others as well.
Wrap with UserControl and set its IsEnabled property.
...