Combo Box with a button in the Items Template - wpf

I would like to add a button to the combobox ItemTemplate, that allows the user to click it and remove the clicked item.
This is what i have so far:
<dxe:ComboBoxEdit Name="cboUserCustomReports"
Width="300" Height="Auto"
Margin="0,5,0,5"
ItemsSource="{Binding Path=UserReportProfileList,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
EditValue="{Binding Path=UserReportProfileID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
ValueMember="UserReportProfileID"
DisplayMember="ReportName"
PopupClosed="cboUserCustomReports_PopupClosed">
<dxe:ComboBoxEdit.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="23"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding XPath=ReportName}"
VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
<Button Grid.Column="1"
Width="23" Height="23"
VerticalAlignment="Center" HorizontalAlignment="Right">
<Button.Template>
<ControlTemplate>
<Image Source="/RMSCommon;component/Resources/Delete.ico"></Image>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</DataTemplate>
</dxe:ComboBoxEdit.ItemTemplate>
</dxe:ComboBoxEdit>
My problem is that my Displaymember is not showing in the TextBlock and only the image of the button template is showing.
Here is a picture of what it looks like:
How do i solve my problem?
Thanks

DisplayMember will not work if you have defined a DataTemplate. However I have seen that you have a TextBlock with a XPath-binding to ReportName. This should do the trick. Check this binding, I assume that there in is the mistake. Check the Visual Studio output-window for binding errors.
<TextBlock Grid.Column="0"
Text="{Binding XPath=ReportName}"
VerticalAlignment="Stretch" HorizontalAlignment
Are you shure that you need an XPath-binding? If you're not sure, try to replace Text="{Binding XPath=ReportName}" through Text="{Binding ReportName}". Maybe this is the only problem.

Related

silverlight combobox template binding

I am trying to bind a combobox from a static resource(added on code behind) and add an image beside each item. The best solution I have so far is the following:
<ComboBox x:Name="cmbGroup"
Width="150" Height="32" ItemsSource="{StaticResource Groups}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="Question.jpg" Height="30" MouseEnter="Image_MouseEnter" ></Image>
<ComboBoxItem Content="{Binding Source={StaticResource Groups}}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This is not working, although I can see the image on each item, but instead a text, I got a "Systems.Collection.GenericList". Any ideas how to solve this? Thanks
When you have a control using Binding inside your datatemplate, it is bound to each item in the ItemsSource collection. Also, if you want to display just the string you can use the TextBlock control instead of ComboboxItem. So, if your code looks like:
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="Question.jpg" Height="30" MouseEnter="Image_MouseEnter" ></Image>
<TextBlock Text="{Binding}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I think you will achieve the effect you are looking for.
Hope this helps.
I guess your "Groups" is a a List?
So you configure your template to display an image, and your object Groups by default.
Thus it displays your groups object: ie the toString() of your Groups, which for a List is "Systems.Collection.GenericList".
My guess is that you bind the bad thing? You want to bind an item of your list, which should have a more suitable toString() version.
Let's say you have some Users item in your Groups List. Thus you binding should look like this:
<ComboBox x:Name="cmbGroup"
Width="150" Height="32" ItemsSource="{StaticResource Groups}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="Question.jpg" Height="30" MouseEnter="Image_MouseEnter" ></Image>
<ComboBoxItem Content="{Binding Source={StaticResource Users}}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Hope it helps

Autoresize ListBox inside ScrollViewer

In my application I have a Window. It contains a left side menu, a header and a place for content.
This content is being loaded dynamically - a UserControl is put in there. These UserControls are various. From just a TextBlock to quite complex pages. To make sure all the content will be visible I have to wrap it with a ScrollViewer (I mean in MyWindow.xaml). It all works fine until I need to put a ListView in the content.
More or less the code looks like that:
<ScrollViewer> // this is the wrapping viewer actually it's in a different file
<UserControl>
......
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding Entities}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Style="{StaticResource Value}" Text="{Binding WorkOrderNumber}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding ActionType}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding StartDate}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding StopDate}"/>
<Separator/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Whatever.. Grid.Row="0" Grid.Column="1"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource CustomButton}" Content="Previous" />
<Button Style="{StaticResource CustomButton}" Content="Current" />
<Button Style="{StaticResource CustomButton}" Content="Next" />
</StackPanel>
</Grid>
</UserControl>
</ScrollViewer>
The result is that the listbox has no scrollbar and gets vary high. The scrollbar is only at the window's scrollviewer.
So in my UserControl I want:
the buttons always to be at the very bottom
the listbox to fill the whole space left (also to resize along with the window)
avoid hardcoding listbox's height
Is that possible?
Use a DockPanel instead of a Grid. DockPanel has a property called LastChhildFill. It is by default true. If you set your ListBox to be the last Child, it will fill all the space:
<ScrollViewer>
<DockPanel>
<StackPanel DockPanel.Dock="Bottom"
Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Style="{StaticResource CustomButton}"
Content="Previous" />
<Button Style="{StaticResource CustomButton}"
Content="Current" />
<Button Style="{StaticResource CustomButton}"
Content="Next" />
</StackPanel>
<ListView >
</ListView>
</DockPanel>
</ScrollViewer>
But this setting makes the Buttons to disappear. I mean they are always at the Bottom of the ListBox. So maybe you need to remove the ScrollViewer.

WPF Statusbar, stretch textblock to take as much space as possible

I created my own simple statusbarcontrol with 3 TextBlocks. Now I would like that the first Textblock takes as much space as it has available. That I don't seem to get done.. Now it only takes the space needed to display the text.
XAML:
<StatusBar Background="{StaticResource GradientBrush}">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem HorizontalAlignment="Left"
HorizontalContentAlignment="Right">
<Border BorderThickness="1"
BorderBrush="Black"
Padding="5 0 5 0"
Background="White">
<TextBlock Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding TextColorMessage}"
Background="White"
/>
</Border>
</StatusBarItem>
<Separator Grid.Column="1" />
<StatusBarItem Grid.Column="2"
HorizontalAlignment="Right">
<TextBlock Text="{Binding Path=DatabaseName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StatusBarItem>
<Separator Grid.Column="3" />
<StatusBarItem Grid.Column="4"
HorizontalAlignment="Right">
<TextBlock Text="{Binding Path=ComputerName}" />
</StatusBarItem>
Well this is pretty straight forward:
you had set the StatusBarItem HorizontalAlignment="Left" when it should be "strech", same for the HorizontalContentAlignment.
Also would suggest setting margin=0 on the border.
this is what i did so it will work for me:
<StatusBarItem HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<Border BorderThickness="1"
BorderBrush="Black"
Margin="0"
Padding="5 0 5 0"
Background="White">
<TextBlock Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding TextColorMessage}"
Background="White"/>
</Border>
</StatusBarItem>
if this is helpful please mark as answer
Try setting the StatusBarItem's HorizontalAlignment and HorizontalContentAlignment to Stretch.
Set the StatusBarItem's HorizontalContentAlignment to Stretch and the TextBlock's TextAlignment property to Right. (This second setting is only needed for the first StatusBarItem as it seems that you try to align the text to the right in it.)
StatusBar has only one HorizontalAlignment=Right item to effect, so you can get only the last item in wanted place. You can set statusBar's FlowDirection="RightToLeft" and add item in reversed order. Details: right placed items needn't StatusBarItem surrounded, but the left one need to be streched. Following code:
<StatusBar VerticalAlignment="Bottom" FlowDirection="RightToLeft"><!--flow right to left cause items right aligned-->
<!--make item's flow back left to right, avoid display disorder-->
<TextBlock x:Name="textBlock_status_R1" Text="111.147.168.20" Grid.Column="2" Margin="10,0" FlowDirection="LeftToRight"/>
<Separator/>
<TextBlock x:Name="textBlock_status_R2" Text="Working" Margin="10,0" FlowDirection="LeftToRight"/>
<Separator/>
<!--To fill rest space,need StatusBarItem packing and default HorizontalAlignment="Stretch"-->
<StatusBarItem FlowDirection="LeftToRight">
<TextBlock x:Name="textBlock_status_L1" Text="Information here."/>
</StatusBarItem>
</StatusBar>

Access ListBoxItem-Controls from code-behind

in my Silverlight 4 application I have a listbox for which I created an itemtemplate:
<DataTemplate x:Key="ItemTemplate">
<Grid Background="{StaticResource BrushCharacteristicListBoxItemBackground}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="TextBlockCharacteristicName" Text="{Binding Name}" TextTrimming="WordEllipsis" ToolTipService.ToolTip="{Binding Name}" Margin="6,0,2,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBlock x:Name="TextBlockSeperator" Text="=" Grid.Column="1" VerticalAlignment="Center" />
<Border Grid.Column="2" HorizontalAlignment="Right" Margin="2,2,6,2" Background="{Binding FunctionState, Converter={StaticResource ConvertCharacteristicFunctionState2Color}}">
<TextBlock x:Name="TextBlockCharacteristicValue" Text="{Binding CalculatedValue, Converter={StaticResource ConvertDouble2Display}}" Padding="2,0" Foreground="{StaticResource BrushCharacteristicListBoxItemBackground}" ToolTipService.ToolTip="{Binding ValueOrFunc}" MaxWidth="72"/>
</Border>
</Grid>
</DataTemplate>
Now I want to access the Controls defined in the template (i.e. TextBlockCharacteristicName) from the code behind. I need this to manually adapt the size of the Controls, which can't be done in an other way.
I hooked into the LayoutUpdated event, but did not found a way to access the controls.
I have tried it with
((StackPanel)ListBoxCharacteristics.GetItemsHost()).Children
which gives me a the list of the ListBoxItems, but there seems to be no way to get the controls from there. Can anyway help me out with this problem?
Thanks in advance,
Frank
Get the small VisualTreeEnumeration chunk of code from this blog: Visual Tree Enumeration.
Now you can find your "TextBlockCharacteristicName" elements with this code:-
foreach (var textBlock in ListBoxCharacteristics.Descendents()
.OfType<TextBlock>()
.Where(t => t.Name == "TextBlockCharacteristicName") )
{
// Do stuff with each Text block.
}

How keep drop down opened in silverlights ComboBox?

I use ComboBox control as popup. Item for my ComboBox is Grid. There is TreeView control and two Buttons in grid. Items of TreeView are CheckBoxes.
When I click on Buttons or CheckBoxes drop down keeps opened, but when I click on other part of grid drop down i closed.
Is there any way to keep it opened until I click outside of ComboBox?
I have looked a lot in Google, but haven't found anything.
<UserControl.Resources>
<common:HierarchicalDataTemplate x:Key="HierarchicalDataTemplate_AddDivision" ItemsSource="{Binding DivisionIDs}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Click="CheckBox_Click" />
<TextBlock Text="{Binding ToDisplay}"/>
</StackPanel>
</common:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.90*"/>
<RowDefinition Height="0.10*"/>
</Grid.RowDefinitions>
<controls:TreeView Height="250" x:Name="itemsToShow" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="230"
Grid.ColumnSpan="2" ItemTemplate="{StaticResource HierarchicalDataTemplate_AddDivision}" SelectedItemChanged="itemsToShow_SelectedItemChanged" />
<Button Margin="28,0,22,5" Content="Ok" Grid.Row="1" d:LayoutOverrides="Height" Click="OkButton_Click"/>
<Button Margin="23,0,27,5" Content="Cancel" Grid.Column="1" Grid.Row="1" d:LayoutOverrides="Height" Click="CancelButton_Click"/>
</Grid>
And this is ComboBox
<ComboBox Grid.Row="1" Width="100" Height="20" HorizontalAlignment="Left" VerticalAlignment="Top" >
<ComboBox.ItemTemplate>
<DataTemplate>
<my1:ShowDivisions x:Name="ShowDivs" Loaded="ShowDivs_Loaded" ParentComboBox="{Binding ElementName=addStr2}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
It sounds like your buttons are not filling all the space in the dropdown part of the ComboBox.
In that case you just need to have a a clickable object behind the buttons to eat any stray mouse clicks:
Try a rectangle with the background set to Transparent (not just a colour with 0 alpha value, as that is not clickable).
(Make sure the rectangle has IsHittestVisible set as well).

Resources