set default string name on combobox - wpf

I am using a Combobox whose ItemSource is ObservableCollection(i.e. ConversationList) of type .
<ComboBox x:Name="ConvId"
Grid.Row="2"
Width="75"
Height="23"
Margin="6,94,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ItemsSource="{Binding ConversationList,
UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedId,
Mode=TwoWay}">
My requirement is : when there is no int value in Collection then Combobox Left side should display 'ConvId' which is a string. Fig. is shown below
I have workaround i.e to Convert collection from int to string and put 'ConvId' on 0th location and mark SelectedIndex= 0. but its not we want.
Do I have to use some Custom control for this. Is there any to acheive this in XAML.

This Stack thread seems to do what you want cleanly with a Converter.
How to display default text "--Select Team --" in combo box on pageload in WPF?
The answer I am referring to starts with this:
<Grid>
<ComboBox
x:Name="comboBox1"
ItemsSource="{Binding MyItemSource}" />
<TextBlock
Visibility="{Binding SelectedItem, ElementName=comboBox1, Converter={StaticResource NullToVisibilityConverter}}"
IsHitTestVisible="False"
Text="... Select Team ..." />
</Grid>

Have below textblock below your combobox and make sure that both combobox and textblock are overlapping each other(i.e. they should be in same grid row)
<TextBlock Text="ConvID"
IsHitTestVisible="False">
<TextBlock.Style>
<Style
TargetType="TextBlock">
<Setter
Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger
Binding="{Binding ConversationList.Count}"
Value="0">
<Setter
Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Hope this helps.

Have a look at the WatermarkService by John Myczek. You can have it display a default string if no item is selected in the ComboBox. There's some issues with ComboBox in the answer I linked to, but if you look further down there's a fix for that.

Related

Create combobox with different items design using data trigger

I have defined the names and color in the backend using C# so I want to select the item cat and change it's other elements.
You don't show the XAML you are using to set up the ComboBox but best approach is to use a data template to set up the ComboBox items however you wish them to look. If you want the color box to not be shown if the Color brush is null, you could then add a trigger to the template to make it Hidden. Note that if you make it collapsed it will realign the layout of the other controls.
<DataTemplate x:Key="cbDataTemplate">
<StackPanel Orientation="Horizontal">
<Rectangle x:Name="clrBox" Fill="{Binding Color, TargetNullValue=Transparent}"
Stroke="Black" StrokeThickness="2" Width="16"/>
<TextBlock Text="{Binding Name}" Margin="10,0,0,0"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Color}" Value="{x:Null}">
<Setter TargetName="clrBox" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
then to use this DataTemplate simply add it to the ComboBox like this:
<ComboBox ItemTemplate="{StaticResource cbDataTemplate}" Width="150"/>
hope that's helpful...

How to set the Control Visibilty of the Second Control depending on the Binding Value of the first

I have a Custom Wpf Control i.e. combobox:WpfTwComboBox. I want to set the visibility using a property called DisableProviderSelector.
The usual use of triggers is not helping. The scenario here is when the above control i.e. WindowsFormsHost is made visible or collapsed, I want the opposite to happen to the below custom control.
<StackPanel Grid.Row="3" Grid.Column="2" Height="25" Orientation="Horizontal"
Width="375" HorizontalAlignment="Left">
<WindowsFormsHost Height="25" Width="375">
<WindowsFormsHost.Style>
<Style TargetType="WindowsFormsHost">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DisableProviderSelector}" Value="true">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DisableProviderSelector}" Value="false">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</WindowsFormsHost.Style>
<commonControls:ProviderSelectorControl RequiredLevel="Save" ModifiedByUser="providerSelectorControl1_ModifiedByUser" x:Name="providerSelectorControl1"/>
</WindowsFormsHost>
<combobox:WpfTwComboBox x:Name="PortalProviderSelector"
SelectedValue="{Binding SelectedPortalProvider}"
ItemsSource="{Binding Path=PortalProvidersCollection}"
DisplayMemberPath="FullName" Width="350" Height="25"
RequiredLevelFlag="Save">
</combobox:WpfTwComboBox>
</StackPanel>
Can anyone please help me on how to set the visibility here?
So DisableProviderSelector is a bool when set to True WindowsFormsHost needs to be Collapsed and ComboBox needs to be Visible. Reverse when bool is false.
So as far as the ComboBox is concerned if bool is True it's Visible and when False it's Collapsed. Thus just bind the ComboBox directly to the Property and use a BooleantoVisibilityConverter
xaml:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
...
<combobox:WpfTwComboBox x:Name="PortalProviderSelector"
Width="350"
Height="25"
DisplayMemberPath="FullName"
ItemsSource="{Binding Path=PortalProvidersCollection}"
RequiredLevelFlag="Save"
Visibility="{Binding DisableProviderSelector,
Converter={StaticResource BooleanToVisibilityConverter}}"
SelectedValue="{Binding SelectedPortalProvider}" />

Set properties of text box when combobox selection is made WPF XAML

how to Set properties of text box when combobox selection is made . foe example set background and IsEnabled property of text box when a combo box selection is made. I want it Purely in XAML not in code behind. i use MVVM
How to enable textBox1 only when SelectedItems is 1
<TextBox Height="23" HorizontalAlignment="Left" Margin="246,177,0,0" Name="textBox2" VerticalAlignment="Top" Width="120">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="IsEnabled" Value="False"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=comboBox1, Path=SelectedIndex}" Value="1">
<Setter Property="Background" Value="Green"></Setter>
<Setter Property="IsEnabled" Value="True"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<ComboBox Height="22" HorizontalAlignment="Left" Margin="246,119,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" />
I think only with XAML you cannot achieve the condition Value ="1" or "3", i.e. a relation in a data trigger more complex than a equality.
For this case you need a converter.
This link could help you
How to get DataTemplate.DataTrigger to check for greater than or less than?
You can use a datatrigger for combo's selected object. Have a look to this previous question: WPF Visibility of a UI element based on combo selection
Try to generate a trigger when selecteditem is {x:Null}. For that, you will need to put your controls inside a DataTemplate and the put the trigger in the template's triggers collection.
Here is a sample code (not tested, please check by your own):
<TextBox Height="23" HorizontalAlignment="Left" Margin="246,177,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" IsEnabled" Value="True" />
<ComboBox Height="22" HorizontalAlignment="Left" Margin="246,119,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" />
<DataTemplate.Triggers>
<Trigger SourceName="comboBox1" Property="ComboBox.SelectedItem" Value="{x:Null}">
<Setter TargetName="textbox2" Property="TextBox.IsEnabled" Value="False" />
</Trigger>
</DataTemplate.Triggers>

ListBox item template depends on item values

In WPF, MVVC applicaiton I have quite normal listbox:
<ListBox ItemsSource="{Binding Friends}">
</ListBox>
Then each item of list uses following datatemplate:
<DataTemplate DataType="{x:Type model:Friend}">
<Border BorderThickness="1" BorderBrush="Gray" Padding="3" Name="border" Margin="3">
<StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal">
<TextBlock Name="DescriptionDTDataType" Text="{Binding Path=ConnectedUserID}" />
<TextBlock Name="StatusTitle" Margin="8,0,4,0">Status:</TextBlock>
<TextBlock Name="Status" Text="{Binding Path=Approved}" />
<Button Content="Approve" Command="{x:Static inf:Commands.ApproveUserConnection}" CommandParameter="{Binding}"></Button>
<Button Content="Disapprove" Command="{x:Static inf:Commands.DisapproveUserConnection}" CommandParameter="{Binding}"></Button>
</StackPanel>
</Border>
</DataTemplate>
The question is... I want to hide one of the buttons on the basic of Friend.Approved property. For example if Friend.Approved has value "approved" I want to hide button Approved and show only button Dissaprove. On the other hand if Friend.Approved has value "disapproved" then I want opposite. How to achieve this?
Thank you.
Beside creating a IValueConverter there is a pure XAML solution using DataTriggers
Just add this to your DataTemplate:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Approved}" Value="approved" >
<Setter TargetName="Approve" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Approved}" Value="disapproved" >
<Setter TargetName="Disapprove" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
And name your buttons:
<Button Name="Approve" Content="Approve" ...></Button>
<Button Name="Disapprove" Content="Disapprove" ...></Button>
However if you want to reuse this hiding logic in multiple places in multiple DataTemplates its better to write the Approved text to Visibility converter.
Bind the Buttons Visibility property to Approved and use a value converter to convert Approved to a Visibility value.

Show "No record found" message on a WPF DataGrid when it's empty

If there is no record available, I want to add a TextBlock on data grid, below the header, showing the message "No Record Found."
Consider the attached image for reference.
Its been a long time since the question has been posted. But I thought this might be useful to someone else.
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<DataGrid Name="dgProjects" ItemsSource="{Binding Projects}" AutoGenerateColumns="True" />
<TextBlock Text="Employee has no projects" Visibility="{Binding Items.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=dgProjects}" />
For simplicity purpose I have set AutoGenerateColumns="True". Please define the columns. This way when a empty datasource is bound, the column names will be shown along with 'Empty row' message.
Finally I am able to findout the way.
When the grid in empty, add a default row on grid
Create a RowDetailTemplate which contain a text block with a message "No Record Found"
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="No Record Found" Width="400"></TextBlock>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
Set the style on datagrid
<DataGrid.Style>
<Style TargetType="DataGrid">
<Setter Property="RowDetailsVisibilityMode" Value="Collapsed"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.IsRecordExists,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type local:MainWindow}}}" Value="false">
<Setter Property="RowHeight" Value="0"></Setter>
<Setter Property="RowDetailsVisibilityMode" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
By default (record available on datagrid) row detail template will be collapsed.
DataTrigger that checks CLR poperty, if it is false then show the row detail template.
The reason for setting the rowheight as 0 to hide the default row which we haved added on 1st step.
Add the grid inside the stackpanel
Place below border code next to datagrid
<Border HorizontalAlignment="Stretch" VerticalAlignment="Center"
BorderThickness="1,0,1,1" BorderBrush="Black" Height="35">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding YourListName.Count}" Value="0">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="No record fount" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
It will show/hide based on your collection/list count.
I find that it is easy to center a text block over the grid and set its visibility based on the number of rows. I am usually using MVVM and will bind the visibility to a View Model property:
<Grid>
<toolkit:DataGrid>
<toolkit:DataGrid.Columns>
.
.
.
</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
<TextBlock Text="No Records Found" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding EmptyMessageVisibility, Mode=OneWay, FallbackValue=Visible}" />
</Grid>

Resources