Monday, December 29, 2014

Dynamically change column width in Reporting Services 2010

I have a requirement to hide/show columns in a Table depending on the type of document being reported and adjust another column's width to compensate. Changing a column's visibility according to a formula is easy, however there is no facility to change a column's width without using code, which is still a pain in the **** in Reporting Services.

Here are the three formats I need to support...

VENDOR requires an Item Number column and a wide Description


STORES requires a Stock Number column and a wide Description

VFS requires an Item Number column and a Stock Number column and a narrow Description.

Hiding a column is easy - you right click the column's tag, click on column visibility, check the 'Show or hide based on an expression', and then enter the Hidden value. I need to hide the Stock Number column for VENDOR documents so...

But how can you change the width of a column without a Dante-like descent into code?

Fortunately Item Number and Stock Number are both the same width (I made them 0.75" each). That means the Description column needs to be 0.75" narrower when the document is VFS.

I created a new column 0.75" wide to the right of the Description column and merged the header and body cells of the Description column with the header and body cells of the new column. With the Description column's tag selected the report designer looks like this...


Then I told Reporting Services to hide the new column when the document is VFS.


Wednesday, December 3, 2014

Changing SelectedIndex on one combo box triggers SelectionChanged event on a different combo box

WPF 4.0

I just spent ten minutes trying to figure out why changing the selected index on one combo box triggers the SelectionChanged event on a different combo box.

The two combo boxes are defined thus...

<ComboBox Name="SearchTransactionTypeCombo" Binding="{StaticResource TransactionTypes}"  SelectedValuePath="GLTransactionTypeID" DisplayMemberPath="Code" Style="{StaticResource DropDownList}"></ComboBox>

<ComboBox Name="EditTransactionTypeCombo" Binding="{StaticResource TransactionTypes}"  SelectedValuePath="GLTransactionTypeID" DisplayMemberPath="Code" Style="{StaticResource DropDownList}" SelectionChanged="TransactionTypeCombo_SelectionChanged" ></ComboBox>

When I change SearchTransactionTypeCombo.SelectedIndex in code the TransactionTypeCombo_SelectionChanged event is raised and the sender object is EditTransactionTypeCombo. How can this be?

Eventually I thought to look at the DropDownList style in case I had declared an EventSetter in there. Here is the style definition...

    <Style TargetType="{x:Type ComboBox}" x:Key="DropDownList" BasedOn="{StaticResource {x:Type ComboBox}}">
        <Setter Property="IsEditable" Value="False"/>
        <Setter Property="IsSynchronizedWithCurrentItem" Value="True"/>
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
    </Style>

The problem is the IsSynchronizedWithCurrentItem property. Both combo boxes are bound to the same resource. When I changed SearchTransactionTypeCombo.SelectedIndex the current row of the collection was changed, which in turn changed the selected index of EditTransactionTypeCombo which raised the TransactionTypeCombo_SelectionChanged event.

As synchronization is not really needed, I removed it from the style. Alternatively I could have bound to different resources, or overridden synchronization in the control definitions.