如何在WPF頁面加載的組合框中顯示默認文本“ - 選擇團隊 - ”?


Answers

我發現最簡單的方法是:

<ComboBox Name="MyComboBox"
 IsEditable="True"
 IsReadOnly="True"
 Text="-- Select Team --" />

您顯然需要添加其他選項,但這可能是最簡單的方法。

然而,這種方法有一個缺點,那就是組合框中的文本不可編輯,它仍然是可選的。 然而,鑑於迄今為止我發現的每一種替代品的質量和復雜性都很差,這可能是最好的選擇。

Question

在WPF應用程序中,在MVP應用程序中,我有一個組合框,為此我顯示從數據庫獲取的數據。 在項目添加到組合框之前,我想顯示默認文本,如

“ - 選擇團隊 - ”

以便在頁面加載時顯示並選擇它,文本應該被清除並且應該顯示項目。

正在從數據庫中選擇數據。 我需要顯示默認文本,直到用戶從組合框中選擇一個項目。

請指導我




我在將代碼隱藏數據庫中的數據綁定到組合框之前做到了這一點 -

Combobox.Items.Add("-- Select Team --");
Combobox.SelectedIndex = 0;



沒有人說純粹的xaml解決方案必須是複雜的。 這是一個簡單的例子,在文本框中有1個數據觸發器。 根據需要設定保證金和頭寸

<Grid>
    <ComboBox x:Name="mybox" ItemsSource="{Binding}"/>
    <TextBlock Text="Select Something" IsHitTestVisible="False">
           <TextBlock.Style>
                <Style TargetType="TextBlock">
                      <Setter Property="Visibility" Value="Hidden"/>
                      <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=mybox,Path=SelectedItem}" Value="{x:Null}">
                                  <Setter Property="Visibility" Value="Visible"/>
                             </DataTrigger>
                      </Style.Triggers>
                </Style>
           </TextBlock.Style>
     </TextBlock>
</Grid>



最簡單的方法是使用CompositeCollection直接在ComboBox中合併來自數據庫的默認文本和數據

    <ComboBox x:Name="SelectTeamComboBox" SelectedIndex="0">
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <ComboBoxItem Visibility="Collapsed">-- Select Team --</ComboBoxItem>
                <CollectionContainer Collection="{Binding Source={StaticResource ResourceKey=MyComboOptions}}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>

並且在資源中定義StaticResource以將ComboBox選項綁定到您的DataContext,因為CollectionContainer中的直接綁定無法正常工作。

<Window.Resources>
    <CollectionViewSource Source="{Binding}" x:Key="MyComboOptions" />
</Window.Resources>

這樣你就可以在xaml中定義你的ComboBox選項

   <ComboBox x:Name="SelectTeamComboBox" SelectedIndex="0">
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <ComboBoxItem Visibility="Collapsed">-- Select Team --</ComboBoxItem>
                <ComboBoxItem >Option 1</ComboBoxItem>
                <ComboBoxItem >Option 2</ComboBoxItem>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>



IceForge的答案非常接近,並且AFAIK是解決這個問題的最簡單的解決方案。 但它錯過了一些東西,因為它不起作用(至少對我而言,它從未實際顯示文本)。

最後,當組合框的選定項不為空時,您不能只將TextBlock的“可見性”屬性設置為“隱藏”,以便隱藏它; 你必須默認設置它(因為你不能在觸發器中使用XAML中的Setter來檢查觸發器中是否為null) 。

以下是基於他的實際解決方案,缺少的Setter放置在觸發器之前:

<ComboBox x:Name="combo"/>
<TextBlock Text="--Select Team--" IsHitTestVisible="False">
    <TextBlock.Style>
        <Style TargetType="TextBlock">

            <Style.Setters>
                <Setter Property="Visibility" Value="Hidden"/>
            </Style.Setters>

            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=combo,Path=SelectedItem}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>



只能將IsEditable屬性設置為true

<ComboBox Name="comboBox1"            
          Text="--Select Team--"
          IsEditable="true"  <---- that's all!
          IsReadOnly="true"/>



有點晚了,但..

更簡單的方法是用參數IsDummy = true向列表中添加一個虛擬數據項,並確保它不是HitTestVisable,其高度為1像素(使用Converter),因此不會被看到。

除了註冊到SelectionChanged並在其中,將索引設置為虛擬物品索引。

它就像一個魅力,這樣你就不會混淆組合框或應用程序主題的風格和顏色。




不是最好的做法..但工作得很好...

<ComboBox GotFocus="Focused"  x:Name="combobox1" HorizontalAlignment="Left" Margin="8,29,0,0" VerticalAlignment="Top" Width="128" Height="117"/>

後面的代碼

public partial class MainWindow : Window
{
    bool clearonce = true;
    bool fillonce = true;
    public MainWindow()
    {
        this.InitializeComponent();          
        combobox1.Items.Insert(0, " -- Select Team --");
        combobox1.SelectedIndex = 0;
    }

    private void Focused(object sender, RoutedEventArgs e)
    {
            if(clearonce)
            {
                combobox1.Items.Clear();
                clearonce = false;
            }
            if (fillonce)
            {
              //fill the combobox items here 
                for (int i = 0; i < 10; i++)
                {
                    combobox1.Items.Insert(i, i);
                }
                fillonce = false;
            }           
    }
}



我在我的項目中使用了IsNullConverter類,它對我很有用。 這裡是它在c#中的代碼,創建一個名為Converter的文件夾並將該類添加到該文件夾中,因為所使用的觸發器不支持value而不是null,並且IsNullConverter只是這樣做

 public class IsNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == null);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException("IsNullConverter can only be used OneWay.");
    }
}

像這樣在xaml文件中添加命名空間。

xmlns:Converters="clr-namespace:TymeSheet.Converter"

手段

xmlns:Converters="clr-namespace:YourProjectName.Converter"

在資源下面使用這一行,通過xaml代碼使其可用

<Converters:IsNullConverter x:Key="isNullConverter" />

這裡是xaml代碼,我在這裡使用了觸發器,所以無論何時在組合框中選擇一個項目時,文本的可見性都會變成錯誤。

<TextBlock Text="Select Project" IsHitTestVisible="False" FontFamily="/TimeSheet;component/Resources/#Open Sans" FontSize="14" Canvas.Right="191" Canvas.Top="22">
                        <TextBlock.Resources>
                            <Converters:IsNullConverter x:Key="isNullConverter"/>
                        </TextBlock.Resources>
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding ElementName=ProjectComboBox,Path=SelectedItem,Converter={StaticResource isNullConverter}}" Value="False">
                                        <Setter Property="Visibility" Value="Hidden"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>



我不知道它是否直接支持,但你可以覆蓋組合標籤,並將其設置為隱藏,如果選擇不為空。

例如。

<Grid>
   <ComboBox Text="Test" Height="23" SelectionChanged="comboBox1_SelectionChanged" Name="comboBox1" VerticalAlignment="Top" ItemsSource="{Binding Source=ABCD}"  />
   <TextBlock IsHitTestVisible="False" Margin="10,5,0,0" Name="txtSelectTeam" Foreground="Gray" Text="Select Team ..."></TextBlock>
</Grid>

然後在選擇更改處理程序...

private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    txtSelectTeam.Visibility = comboBox1.SelectedItem == null ? Visibility.Visible : Visibility.Hidden;
}



基於IceForge的回答,我準備了一個可重複使用的解決方案:

xaml風格:

<Style x:Key="ComboBoxSelectOverlay" TargetType="TextBlock">
    <Setter Property="Grid.ZIndex" Value="10"/>
    <Setter Property="Foreground" Value="{x:Static SystemColors.GrayTextBrush}"/>
    <Setter Property="Margin" Value="6,4,10,0"/>
    <Setter Property="IsHitTestVisible" Value="False"/>
    <Setter Property="Visibility" Value="Hidden"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding}" Value="{x:Null}">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

使用示例:

<Grid>
     <ComboBox x:Name="cmb"
               ItemsSource="{Binding Teams}" 
               SelectedItem="{Binding SelectedTeam}"/>
     <TextBlock DataContext="{Binding ElementName=cmb,Path=SelectedItem}"
               Text=" -- Select Team --" 
               Style="{StaticResource ComboBoxSelectOverlay}"/>
</Grid>



Related



Tags

wpf   combobox