?
Solved

wpf add multiple labels to expander header

Posted on 2011-10-12
12
Medium Priority
?
2,048 Views
Last Modified: 2013-12-16
Hi,

Im wondering if it is possible to add multiple labels to the header of an expander control.

I currently have the header bound to a text value that is a property on an object. I am building this text value based on several other field values on this object.

This works fine but doesn't allow be to add formatting of the various fields. I need to be able to set the foreground colour of the individual field values so i really need to have multiple labels (or similar)  basically 'sitting' on top of the expander header. Is this possible?
0
Comment
Question by:basil365
  • 6
  • 5
12 Comments
 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36955200
<Expander.Header>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Item1" FontWeight="Bold"></TextBlock>
        <TextBlock Text="Item2"></TextBlock>
    </StackPanel>
</Expander.Header>

Instead of hard-coded Text property values you can use data-binding expression.
Even you can use different container instead of StackPanel.
0
 

Author Comment

by:basil365
ID: 36961153
Apologies for the late reply - my account expired :/

That works fine and displays the values declared in the xaml but doesn't display values i programmatically set
0
 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36961237
Please post XAML showing the Expander and how programmtically do you try to set the values of elements in Header of the Expander.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36961254
You need to set the Name property of the controls and thus you should be able to access them in code.
Like this,

<TextBlock Name="HeaderItem1" Text="Item1" FontWeight="Bold"></TextBlock>
<TextBlock Name="HeaderItem2" Text="Item2"></TextBlock>

Then in code
HeaderItem1.Text = "NewItem1";
0
 

Author Comment

by:basil365
ID: 36961554
i have done that

<Expander.Header>
                <StackPanel Orientation="Horizontal">
                    <TextBlock  Name="lblName" HorizontalAlignment="Left" Text="Name Goes here"></TextBlock >
                    <TextBlock  Name="lblStatus" HorizontalAlignment="Right" Text="Status"></TextBlock >
                    <TextBlock  Name="lblDisplayed" HorizontalAlignment="Right" Text="Displayed"></TextBlock >
                </StackPanel>
            </Expander.Header>          

Open in new window


(excuse the 'lbl' naming - i was trying both labels and textblocks)

then in the code (constructor of the control)

 Binding statusBinding = new Binding { Source = marketDestination, Path = new PropertyPath("Status") };
            //this.lblStatus.SetBinding(Label.ContentProperty, statusBinding);
            this.lblStatus.SetBinding(TextBlock.TextProperty, statusBinding);
            this.lblStatus.Text = marketDestination.Status;

Open in new window

0
 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36962059
Your code is correct. Please check whether "marketDestination" is set as DataContext of the control or not.
I tested it as follows,

private List<EmployeeVM> employeeList;

...

...

this.DataContext = new { Employees = employeeList };

...

...

Then in Button Click I did this

Binding statusBinding = new Binding { Source = employeeList, Path = new PropertyPath("Count") };
this.HeaderItem1.SetBinding(TextBlock.TextProperty, statusBinding);


Here HeaderItem1 is the name of the TextBlock in Header of the Expander. On clicking the button it reflected the correct count.
0
 

Author Comment

by:basil365
ID: 36962543
I actually have no datacontext set.The same code on labels outside the header works correctly.

My bound object is not part of a list (but it does implement INotifyPropertyChanged which allows the binding to work)

I have a different control which works as you suggest above (but again not as part of an expander) that uses IOservableCollection<> as the dataSource, but this control is bound to a single object (with one of its fields containing a second object that has values i also want to display)
0
 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36966934
I tried this way to match the way you are doing it.

public class ContactVM
{
      public string FirstName { get; set; }
      public string LastName { get; set; }
}

ContactVM is the binding source object in my example. It does not implement INotifyPropertyChanged but I don't think that makes difference for our problem at hand.

Next I did this in button click,

ContactVM contact = new ContactVM { FirstName = "Test1", LastName = "Test2" };
Binding statusBinding = new Binding { Source = contact, Path = new PropertyPath("FirstName") };
this.HeaderItem1.SetBinding(TextBlock.TextProperty, statusBinding);

On clicking the button, HeaderItem1 showed "Test1".

It works for me. Do you think I have missed anything in replicating your scenario except INotifyPropertyChanged.

Also, earlier you mentioned you have this code in constructor of the control. I have it in a button click. Another difference I can spot. Can you just test my putting your code in button click as well?
0
 

Author Comment

by:basil365
ID: 36967412
Setting the label under a click event doesn't seem to be working either for some reason

Thanks for your help i'll try various other scenarios and let you know if anything works
0
 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36967657
If you may choose to trace binding errors check this link.

It explains various options we have to trace binding related issues.
0
 
LVL 23

Accepted Solution

by:
Snarf0001 earned 1000 total points
ID: 36969810
This is a problem in your code:

            this.lblStatus.SetBinding(TextBlock.TextProperty, statusBinding);
            this.lblStatus.Text = marketDestination.Status;


The second line is not needed.  As soon as you set the binding, the label will have the marketDestination.Status value set into it.
It actually operates exactly opposite your goal.  When you're doing things in code, as soon as you manuall say lblStatus.Text = <something>, you're actually clearing the binding.
So you're second line is completely nullifying the binding you set in the first line.
0
 

Author Comment

by:basil365
ID: 36978538
Hi, the second line was only put there to see if i was able to programmatically set the value in anyway. The same occurrence happens without it
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question