Klay
Klay

Reputation: 2011

wpf control template

I have a very simple case that I think would benefit from using templates (but I'm not sure, which is why I'm asking). All the templating examples I've seen either assume more knowledge than I have, are too specific to be of much use to a total newb like myself, or contain lots of ancillary stuff that makes it hard to identify what's part of the template.

Here's the setup: I have two labels side-by-side, with the first label populated with the name of a field, and the second label populated with the value of the field.

Here is the XAML I currently have in my app (many, many times):

<StackPanel Style="{StaticResource horizontalStackerStyle}">
    <Label Style="{StaticResource labelStyle}">Field One:</Label>
    <Label Style="{StaticResource valueStyle}" Name="field1" 
        Content="{Binding dataObject.field1}" />
</StackPanel>

I would like to create a template such that I could write XAML like this:

<CustomControlOrWhatever 
    FieldName="Field One:" 
    FieldValue="{Binding dataObject.field1}"/>

I have a feeling I can do this with some kind of template. One benefit of which would be that I don't need to keep specifying the styles over and over. Am I correct? How would I do this?

Thanks in advance!

UPDATE:

Still haven't found an answer to this. I chose a possible solution using Dependency Properties, and tried to ask a clarifying question here. Well, the first responder said that I don't actually need to clutter up my code behind with DP nonsense, so I changed it again--and it still doesn't work. Can anyone come up with a working solution? This seems like it should be so simple.

Just to be clear: this only needs to be one-way binding with values updated every few seconds.

Upvotes: 2

Views: 985

Answers (3)

Brandon
Brandon

Reputation: 69983

What you're asking for is basically a user control.

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SomeNameSpace.SomeControlName">
    <Grid x:Name="LayoutRoot">
     <StackPanel Style="{StaticResource horizontalStackerStyle}">
      <Label Style="{StaticResource labelStyle}" x:Name="FieldNameLbl"></Label>
      <Label Style="{StaticResource valueStyle}" x:Name="ValueLbl">
      </StackPanel>
    </Grid>
</UserControl>

In the code behind, you'd need to expose two properties that would set the value of the controls.

public string FieldName
{
    get { return FieldNameLbl.Text; }
    set { FieldNameLbl.Text = value; }
}

public string FieldValue
{
    get { return ValueLbl.Text; }
    set { ValueLbl.Text = value; }
}

And then to call that you can put this at the top of your window/page with the rest of your declarations:

xmlns:Controls="clr-namespace:SomeNameSpace" 

and then you can insert the control into your window/page like this:

<Controls:NameOfYourControl FieldName="Field One:" FieldValue="{Binding dataObject.field1}"/>

Upvotes: 2

Tiberiu Ana
Tiberiu Ana

Reputation: 3663

What you want to do is similar to the discussion about putting images on a button with a simple way of specifying the path, like <Button MyImage="foo.jpg" />. Follow this article for the actual details.

To summarize:

  • One obvious way would be to create an UserControl containing your two labels and exposing the two properties. Not much templating here.

  • The most WPFish solution seems to be to use two Attached Properties on one of the labels (say the value), and provide a control template for it that includes the other label (the description). In the template, you bind each label text to the corresponding attached property value.

Upvotes: 0

Noldorin
Noldorin

Reputation: 147290

You could create a UserControl called FieldControl and define backing (automatic) properties for FieldName and FieldValue. (Normal properties would be fine, so long as you only need to bind once, which is probably the case.)

The XAML code might look like:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="foo.bar">
    <StackPanel Style="{StaticResource horizontalStackerStyle}">
        <Label Style="{StaticResource labelStyle}" Content="{Binding Path=FieldName, Mode=OneTime, StringFormat='{0}: '}"/>
        <Label Style="{StaticResource valueStyle}" Content="{Binding Path=FieldValue, Mode=OneTime}" />
    </StackPanel>
</UserControl>

Hope that helps.

Upvotes: 1

Related Questions