Dec 19 2007 10:45AM GMT
Posted by: Mark Shurmer
WPF
Have you, like me recently, discovered that you need to create specialised textblocks and add them to an existing TextBlock?
One example would be adding hyperlinks into a block of text.
The TextBlock element has the Inlines property to allow you do that. You can add as many Inline derived elements as you like. So you can add things like plain text, richer text, hyperlinks etc.
You can do it in code, and using static xaml. However, what is more challenging is how to do it through data binding.
You would like to do the following:
<TextBlock>
<Inlines Source=”{Binding Path=blah}” />
</TextBlock>
Unfortunately, you can’t, as Inlines is not a DependencyProperty to start with.
One obvious solution is to subclass the TextBlock, and add a DependencyProperty of type List<Inline>. This works a treat, and the class is :
public class RichTextBlock : System.Windows.Controls.TextBlock
{
public static DependencyProperty InlineProperty
static RichTextBlock()
{
//OverrideMetadata call tells the system that this element wants to provide a style that is different than in base class
DefaultStyleKeyProperty.OverrideMetadata(typeof(RichTextBlock), new FrameworkPropertyMetadata(
typeof(RichTextBlock)));
InlineProperty = DependencyProperty.Register(“RichText”, typeof(List<Inline>), typeof(RichTextBlock),
new PropertyMetadata(null, new PropertyChangedCallback(OnInlineChanged)));
}
public List<Inline> RichText
{
get { return (List<Inline>)GetValue(InlineProperty); }
set { SetValue(InlineProperty, value); }
} public static void OnInlineChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == e.OldValue)
return;
RichTextBlock r = sender as RichTextBlock;
List<Inline> i = e.NewValue as List<Inline>;
if (r == null || i == null)
return;
r.Inlines.Clear();
foreach (Inline inline in i)
{
r.Inlines.Add(inline);
}
}
}
I can’t help but feel that this should be an attached property somehow…..
Dec 13 2007 4:46PM GMT
Posted by: Mark Shurmer
WPF
What seems to be forgotten about the ListView control in WPF, at least by some people, is that it’s more than just a replacement for the DataGridView.
The point behind it is that it separates the data from the way it is presented, so you can have the same data presented in different ways, ie details or icon or list. It seems obvious, but it has been lost in some circles.
The presentation is controlled by the View property, which then creates a ViewBase derived class to do the presenting.
The gotcha is that the ListView in WPF (versions 3.0 and 3.5) only ships with one view - the GridView.
So can you add others, of course you can.
You simply have to derive a new class from ViewBase , draw the elements in the list , plug the new class in and bingo.
Part 2 will go through how you do that!
Dec 12 2007 3:14PM GMT
Posted by: Mark Shurmer
WPF
Have you ever lost the scrollbars in a ListView?
What I mean is, there lots of rows in the ListView, but it’s not displaying any scrollbar, even if you set the ScrollViewer.VerticalScrollBarVisibility property? An example of this is:
<StackPanel>
<ListView Name=”lvInstruments” ScrollViewer.VerticalScrollBarVisibility=”Auto” ScrollViewer.CanContentScroll=”True” >
<rest of listview stuff…./><
/ListView>
<Canvas HorizontalAlignment=”Center” VerticalAlignment=”Center”>
<TextBlock Text=”The instrument may have been invalid or the search too ambiguous” Visibility=”Hidden” Name=”txtError” Style=”{DynamicResource TextBlock Error}” Canvas.Left=”5″ Canvas.Top=”20″ />
</Canvas>
</StackPanel>
Here the canvas is used to locate a textblock over the listview, and though that could have been done other ways, it’s just an exampleWhat you will find with the above example is that there are no scrollbars!
To fix, just change the StackPanel to a WrapPanel, and bisto 
Dec 11 2007 12:37PM GMT
Posted by: Mark Shurmer
WPF
Just how do WPF and Silverlight fit together, if indeed at all?
Well, version 1.0 of Silverlight was released a little while, and to be honest left me cold. Support was lacking for LOB applications, and also developing the code behind in c# - therefore no great interest.
Version 2.0 (aka 1.1 until recently) looks a lot more interesting.
It seems that inclusion of form and layout controls is on the list of things to include, not to mention coding the code behind in c#.
The other question for me was whether we can code in xaml and place that code in a windows wpf program, in an intranet xbap and a silverlight web application without any copying and pasting or fiddly little changes, or having to nastily write xslt transforms to achieve this.
Dec 7 2007 11:30AM GMT
Posted by: Mark Shurmer
C,
WPF
If you want to, for example, to override a control template for a control in WPF, it is quite easy and very powerful.
One great thing is that you can specify a templatebinding instead of a (slightly) convoluted syntax to specify the property you are binding to. An example:
<TextBox Text=“{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ValueString}“
This points the text property, in your template, to gets it’s value from the property called ValueString in the xaml that specifies the textbox instance, however it can be changed to:
<TextBox Text=“{TemplateBinding Path=ValueString}“
Much simpler isn’t it.
It also has the benefit of being more efficient than the first version as well, it justs gets better doesn’t it.
However, there is a downside, as I found to my cost yesterday
It is one-way only, so if you keep wondering why changes are not being propagated back, wonder no more.
If you want two-way, then you need the first version unfortunately
Dec 6 2007 3:42PM GMT
Posted by: Mark Shurmer
WPF
The question i was faced with was how to bind to a current item in an array. Why? I wanted to display the result of the ToString() method on the whole object - it should display something like ‘buy 100 abc.o @ 50′
I had an array (of Equities, but it could have been anything), and some xaml binding to it:
<StackPanel DataContext=“{x:Static EquitiesModel.Equities}“>
<TextBlock Text=“{Binding}“ />
<ListBox ItemsSource=“{Binding}” IsSynchronizedWithCurrentItem=“True“ />
</StackPanel>
That didn’t work because the {Binding} binds to the whole array, and i just needed the current item. It turned out to be some syntax that I hadn’t seen since XPath:
<StackPanel DataContext=“{x:Static EquitiesModel.Equities}“>
<TextBlock Text=“{Binding /}“ />
<ListBox ItemsSource=“{Binding}” IsSynchronizedWithCurrentItem=“True“ />
</StackPanel>
Lo and behold, it used the ToString() method, and I was happy!
Dec 3 2007 11:40AM GMT
Posted by: Mark Shurmer
WPF
Firstly, what are they?
I say they are custom events that you can place into the tree in WPF to add extra functionality without subclassing controls.
The pure MSDN definition is:
“An attached event allows you to attach a handler for a particular event to some child element rather than to the parent that actually defines the event, even though neither the object potentially raising the event nor the destination handling instance define or otherwise ‘own’ that event in their namespace.”
However, you do have to read that quite a few times!
So I’ve broken it down into a few key elements:
- It is a normal WPF routed event
- They are custom events that mean you don’t have to subclass existing classes
- It is not a language event (with += & -= handlers in c#), you use AddHandler and RemoveHandler instead
- You can put them into attributes like standard system events
Hope that’s clear 