จะแสดงข้อความเริ่มต้น“ - เลือกทีม -” ในกล่องคำสั่งผสมบน pageload ใน WPF ได้อย่างไร?


109

ในแอป WPF ในแอป MVP ฉันมีกล่องคำสั่งผสมซึ่งฉันแสดงข้อมูลที่ดึงมาจากฐานข้อมูล ก่อนรายการที่เพิ่มลงในกล่องคำสั่งผสมฉันต้องการแสดงข้อความเริ่มต้นเช่น

"- เลือกทีม -"

เพื่อให้บน pageload แสดงขึ้นและเมื่อเลือกข้อความนั้นควรล้างข้อความและควรแสดงรายการ

การเลือกข้อมูลจาก DB กำลังเกิดขึ้น ฉันต้องการแสดงข้อความเริ่มต้นจนกว่าผู้ใช้จะเลือกรายการจากกล่องคำสั่งผสม

ช่วยชี้แนะด้วยครับ

คำตอบ:


108

วิธีที่ง่ายที่สุดที่ฉันพบคือ:

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

เห็นได้ชัดว่าคุณจะต้องเพิ่มตัวเลือกอื่น ๆ ของคุณ แต่นี่อาจเป็นวิธีที่ง่ายที่สุดที่จะทำ

อย่างไรก็ตามมีข้อเสียอย่างหนึ่งของวิธีนี้คือในขณะที่ข้อความในกล่องคำสั่งผสมของคุณไม่สามารถแก้ไขได้ แต่ก็ยังสามารถเลือกได้ อย่างไรก็ตามเนื่องจากคุณภาพที่ไม่ดีและความซับซ้อนของทุกทางเลือกที่ฉันพบในปัจจุบันนี่อาจเป็นตัวเลือกที่ดีที่สุด


คำตอบที่ดีคริส! ฉันจะเพิ่ม Focusable = "True" แต่นั่นเป็นเพียงการเปลี่ยนแปลงเครื่องสำอาง
Slavisa

6
คำตอบที่สมบูรณ์แบบคริส สถานที่ให้บริการแห่งหนึ่งสามารถสร้างความแตกต่างได้มาก: D
Aster Veigas

4
Focusable="False" IsEditable="True" IsReadOnly="True"
Kamil Lelonek

1
+1. โชคร้ายที่มันใช้ไม่ได้กับไอเท็มผสมกัน (เช่นหากไอเท็ม combobox เป็นรูปภาพ)
greenoldman

11
โซลูชันที่เรียบง่ายและใช้งานได้จริง การควบคุม WPF มีปัญหาประเภทนี้ทั่วทั้งเฟรมเวิร์ก ที่นี่การควบคุมไม่มีคุณลักษณะที่นักพัฒนาส่วนใหญ่ต้องการ เป็นผลให้นักพัฒนาเสียเวลาในการค้นหาโซลูชันซื้อการควบคุมทางเลือกของบุคคลที่สามหรือใช้วิธีแก้ปัญหา ... ทีม WPF ใช้การควบคุมเพื่อการพัฒนาของตนเองหรือไม่?
ผักเหี้ย

90

คุณสามารถทำได้โดยไม่ต้องใส่รหัสใด ๆ ไว้ข้างหลังโดยใช้ไฟล์IValueConverter.

<Grid>
   <ComboBox
       x:Name="comboBox1"
       ItemsSource="{Binding MyItemSource}"  />
   <TextBlock
       Visibility="{Binding SelectedItem, ElementName=comboBox1, Converter={StaticResource NullToVisibilityConverter}}"
       IsHitTestVisible="False"
       Text="... Select Team ..." />
</Grid>

ที่นี่คุณมีคลาสตัวแปลงที่คุณสามารถใช้ซ้ำได้

public class NullToVisibilityConverter : IValueConverter
{
    #region Implementation of IValueConverter

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

และสุดท้ายคุณต้องประกาศตัวแปลงของคุณในส่วนทรัพยากร

<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />

โดย Converters คือสถานที่ที่คุณวางคลาสคอนเวอร์เตอร์ไว้ ตัวอย่างคือ:

xmlns:Converters="clr-namespace:MyProject.Resources.Converters"

สิ่งที่ดีมากเกี่ยวกับแนวทางนี้คือไม่มีการทำโค้ดซ้ำ ๆ ในโค้ดของคุณที่อยู่เบื้องหลัง


ฉันต้องการใช้สิ่งนี้ แต่ดูเหมือนว่าจะไม่ได้รับอนุญาตในกรณีที่ combobox เป็นส่วนหัวของดาต้ากริด . . XAML ให้ข้อผิดพลาดว่ามีการกำหนดส่วนหัวไว้แล้ว (หรืออาจไม่สามารถกำหนดได้มากกว่าหนึ่งครั้ง) ความคิดใด ๆ ? ฉันคิดว่าจะใช้ตัวเลือกค่าว่างซึ่งจะอนุญาตให้รีเซ็ตได้โดยการเลือก แต่ดูเหมือนจะเลอะเทอะเล็กน้อย
Paul Gibson

1
เหตุผลใหญ่ที่นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยมเนื่องจากโครงการ WPF ที่เชื่อมโยงกับข้อมูลทุกโครงการใช้ประโยชน์จาก NullToVisibilityConverter ดังนั้นจึงมีอยู่แล้วเกือบตลอดเวลา - อาจใช้ประโยชน์จากมันด้วยเช่นกัน!
tpartee

2
จริงๆแล้วคุณสามารถใช้ a DataTriggerเพื่อหลีกเลี่ยงแม้แต่รหัสตัวแปลงได้ที่นี่ :)
Billy ONeal

49

ฉันชอบคำตอบของ Tri Q แต่ตัวแปลงค่าเหล่านั้นเป็นเรื่องยากที่จะใช้ PaulB ทำด้วยตัวจัดการเหตุการณ์ แต่ก็ไม่จำเป็นเช่นกัน นี่คือโซลูชัน XAML ที่บริสุทธิ์:

<ContentControl Content="{Binding YourChoices}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox x:Name="cb" ItemsSource="{Binding}"/>
                <TextBlock x:Name="tb" Text="Select Something" IsHitTestVisible="False" Visibility="Hidden"/>
            </Grid>
            <DataTemplate.Triggers>
                <Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="tb" Property="Visibility" Value="Visible"/>
                </Trigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate> 
</ContentControl>

33

ไม่มีใครบอกว่าโซลูชัน 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>

5
ฉันต้องการย้าย "การมองเห็น =" ซ่อน "ไปที่ทริกเกอร์ข้อมูลจากนั้นมันก็ทำงานได้ตามที่คาดไว้แน่นอนว่าเป็นแนวทางที่ตรงไปข้างหน้ามากที่สุดที่ฉันเคยเห็นมาเพื่อความสามารถในการนำกลับมาใช้ใหม่ฉันได้ย้ายรูปแบบไปไว้ในทรัพยากร
Mitch

คำตอบของ @Mitch IceForce ไม่ได้ผลสำหรับฉันคุณเปลี่ยนอะไรเพื่อให้มันใช้งานได้?
คริส

1
@ คริสฉันคิดว่าเขาหมายถึงการเพิ่ม<Setter Property="Visibility" Value="Hidden"/>นอกทริกเกอร์ (ภายในสไตล์) และลบออกVisibility="Hidden"จากองค์ประกอบบล็อกข้อความจริง
คืนสถานะโมนิกาได้โปรด

@Mitch คุณจะย้ายสไตล์ Textblock ไปยังทรัพยากรเพื่อนำมาใช้ใหม่ได้อย่างไรหากคุณมี ElementName ใน DataTrigger ที่ชี้ไปที่วัตถุเฉพาะ (mybox) มีวิธีใดในการระบุชื่อนั้นด้วยวิธีทั่วไปหรือไม่?
CrApHeR

24

ตั้งค่าIsEditable="True"ในComboBoxองค์ประกอบ ซึ่งจะแสดงTextคุณสมบัติของไฟล์ComboBox.


2
นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุดจากทั้งหมด
Sergey Koulikov

6
มันเปลี่ยนลักษณะของการควบคุม
simonalexander2005

16

ฉันไม่รู้ว่ามันรองรับโดยตรง แต่คุณสามารถซ้อนทับคำสั่งผสมด้วยป้ายกำกับและตั้งค่าเป็นซ่อนหากการเลือกไม่เป็นโมฆะ

เช่น.

<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;
}

1
แทนที่จะสร้างตัวจัดการ SelectionChanged การมองเห็นของ TextBlock สามารถตั้งค่าใน XAML ได้
aliceraunsbaek

6

จากคำตอบของ 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>

ดี. ฉันได้ขยายมันโดยการผูก DataContext ของ TextBlock โดยใช้แหล่งที่มาสัมพัทธ์เพื่อหลีกเลี่ยงการตั้งชื่อ ดูความคิดเห็นถัดไปสำหรับมาร์กอัป (รหัสในความคิดเห็นของ SO ดูน่าเกลียด)
Sascha

<TextBlock DataContext = "{Binding Path = Children [0 ].SelectedItem, RelativeSource = {RelativeSource AncestorType = Grid}}" Text = "- Select Project -" Style = "{StaticResource ComboBoxSelectOverlay}" />
Sascha

4

ไม่ได้ลองใช้กับกล่องคำสั่งผสม แต่สิ่งนี้ใช้ได้ผลกับตัวควบคุมอื่น ๆ ...

บล็อกโพสต์ ageektrapped

เขาใช้ชั้นประดับที่นี่เพื่อแสดงลายน้ำ


เพิ่งดาวน์โหลดและลองใช้รหัสนี้ ดูเหมือนว่าจะได้ผลตามที่โฆษณาไว้ ช่วยให้คุณสามารถตกแต่งคำสั่งผสมของคุณด้วยคุณสมบัติที่แนบมาง่ายๆที่มีลายน้ำของคุณ นอกจากนี้ยังใช้งานได้กับส่วนควบคุมอื่น ๆ ด้วย เป็นแนวทางที่ดีกว่าคำตอบอื่น ๆ สำหรับคำถามนี้
Ian Oakes

สิ่งที่ดีไม่เพียง แต่แก้ปัญหา ComboBox แต่ตอนนี้ฉันสามารถกำจัดแอสเซมบลี WPF Tools และใช้สิ่งนี้กับ TextBoxes ของฉันแทนการควบคุม WatermarkedTextBox ด้วยดังนั้นจึงเต็มไปด้วยชัยชนะ :) - โอ้ btw มันเป็น Geek Trapped ไม่ใช่ ตกลงกับดัก!
dain

2

โซลูชันของ HappyNomad นั้นดีมากและในที่สุดฉันก็มาถึงโซลูชันที่แตกต่างกันเล็กน้อยนี้

<ComboBox x:Name="ComboBoxUploadProject" 
    Grid.Row="2"
    Width="200" 
    Height="23"                           
    Margin="64,0,0,0"
    ItemsSource="{Binding projectList}"
    SelectedValue ="{Binding projectSelect}" 
    DisplayMemberPath="projectName"
    SelectedValuePath="projectId"
    >
    <ComboBox.Template>
        <ControlTemplate TargetType="ComboBox">
            <Grid>
                <ComboBox x:Name="cb" 
                    DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" 
                    ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}}"
                    SelectedValue ="{Binding SelectedValue, RelativeSource={RelativeSource TemplatedParent}}" 
                    DisplayMemberPath="projectName"
                    SelectedValuePath="projectId"
                    />
                <TextBlock x:Name="tb" Text="Select Item..." Margin="3,3,0,0" IsHitTestVisible="False" Visibility="Hidden"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="tb" Property="Visibility" Value="Visible"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </ComboBox.Template>
</ComboBox>

2

วิธีที่ง่ายที่สุดคือใช้ 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>

ด้วยวิธีนี้คุณสามารถกำหนดตัวเลือก ComboBox ของคุณได้เฉพาะใน xaml เช่น

   <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>

1

ฉันอยากจะแนะนำสิ่งต่อไปนี้:

กำหนดพฤติกรรม

public static class ComboBoxBehaviors
{
    public static readonly DependencyProperty DefaultTextProperty =
        DependencyProperty.RegisterAttached("DefaultText", typeof(String), typeof(ComboBox), new PropertyMetadata(null));

    public static String GetDefaultText(DependencyObject obj)
    {
        return (String)obj.GetValue(DefaultTextProperty);
    }

    public static void SetDefaultText(DependencyObject obj, String value)
    {
        var combo = (ComboBox)obj;

        RefreshDefaultText(combo, value);

        combo.SelectionChanged += (sender, _) => RefreshDefaultText((ComboBox)sender, GetDefaultText((ComboBox)sender));

        obj.SetValue(DefaultTextProperty, value);
    }

    static void RefreshDefaultText(ComboBox combo, string text)
    {
        // if item is selected and DefaultText is set
        if (combo.SelectedIndex == -1 && !String.IsNullOrEmpty(text))
        {
            // Show DefaultText
            var visual = new TextBlock()
            {
                FontStyle = FontStyles.Italic,
                Text = text,
                Foreground = Brushes.Gray
            };

            combo.Background = new VisualBrush(visual)
            {
                Stretch = Stretch.None,
                AlignmentX = AlignmentX.Left,
                AlignmentY = AlignmentY.Center,
                Transform = new TranslateTransform(3, 0)
            };
        }
        else
        {
            // Hide DefaultText
            combo.Background = null;
        }
    }
}

ใช้พฤติกรรม

<ComboBox Name="cmb" Margin="72,121,0,0" VerticalAlignment="Top"
          local:ComboBoxBehaviors.DefaultText="-- Select Team --"/>

สิ่งนี้ใช้งานได้เหมือนเสน่ห์สำหรับกล่องคำสั่งผสมเดียว แต่เมื่อฉันใช้กับมากกว่า 1 คำสั่งผสมมันทำให้ฉันมีข้อผิดพลาด (แต่คอมไพล์และทำงานได้ดี) "คุณสมบัติ" DefaultText "ที่ลงทะเบียนแล้วโดย" ComboBox "" ฉันได้กล่าวถึงการแก้ไขในบล็อกของฉัน
Romesh D. Niriella

ขอบคุณที่ชี้ให้เห็น ฉันไม่สามารถสร้างข้อผิดพลาดนี้บนคอมพิวเตอร์ของฉัน อย่างไรก็ตามฉันยอมรับว่าควรส่ง typeof (ComboBoxBehaviors) ในพารามิเตอร์ที่ 3 ของ RegisterAttached แทน typeof (ComboBox)
Usman Zafar

แม้ว่าโพสต์นี้จะเก่าไปหน่อย แต่ฉันไม่เห็นว่ามันจะทำงานได้อย่างไร bg ของคำสั่งผสมถูกตั้งค่าผ่านทริกเกอร์ที่มีหลายเงื่อนไข ลองวางคำสั่งผสมเพียงอย่างเดียวบนตารางและตั้งค่า bg ด้วยตนเองเป็น "สีแดง" ไม่มีผลกระทบต่อพื้นที่ที่คุณต้องการให้ลายน้ำปรากฏ อาจมีผลกับ bg ที่อยู่ด้านหลังแผงแบบเลื่อนลงเท่านั้น วิธีแก้ปัญหาที่ดีกว่าคือการคัดลอกเทมเพลตการควบคุมของคอมโบบ็อกซ์และเพิ่มทริกเกอร์และสไตล์เล็กน้อยเพื่อวาดพู่กันภาพที่ประกอบด้วยบล็อกข้อความลงในพื้นหลังของเส้นขอบ
Newclique

1

คำตอบของ IceForgeนั้นค่อนข้างใกล้เคียงและ AFAIK เป็นวิธีแก้ปัญหาที่ง่ายที่สุดสำหรับปัญหานี้ แต่มันพลาดบางอย่างไปเพราะมันใช้งานไม่ได้ (อย่างน้อยสำหรับฉันมันไม่เคยแสดงข้อความจริงๆ)

ในท้ายที่สุดคุณไม่สามารถตั้งค่าคุณสมบัติ "การมองเห็น" ของ TextBlock เป็น "ซ่อน" เพื่อให้ซ่อนได้เมื่อรายการที่เลือกของกล่องคำสั่งผสมไม่เป็นโมฆะ คุณต้องตั้งค่าเป็นค่าเริ่มต้น (เนื่องจากคุณไม่สามารถตรวจสอบไม่ว่างในทริกเกอร์โดยใช้ Setter ใน XAML ที่เดียวกับทริกเกอร์

นี่คือวิธีแก้ปัญหาที่เกิดขึ้นจริงโดยอ้างอิงจาก Setter ที่ขาดหายไปซึ่งวางอยู่หน้า Triggers:

<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>

1

แก้ไข: ตามความคิดเห็นด้านล่างนี่ไม่ใช่วิธีแก้ปัญหา ไม่แน่ใจว่าฉันทำงานอย่างไรและไม่สามารถตรวจสอบโครงการนั้นได้

ถึงเวลาอัปเดตคำตอบสำหรับ XAML ล่าสุดแล้ว

การค้นหาคำถาม SO นี้เพื่อค้นหาวิธีแก้ปัญหาสำหรับคำถามนี้ฉันพบว่าข้อมูลจำเพาะ XAML ที่อัปเดตมีวิธีง่ายๆ

ขณะนี้แอตทริบิวต์ที่เรียกว่า "ตัวยึดตำแหน่ง" พร้อมใช้งานเพื่อทำงานนี้ให้สำเร็จ ทำได้ง่ายเพียงเท่านี้ (ใน Visual Studio 2015):

<ComboBox x:Name="Selection" PlaceholderText="Select...">
    <x:String>Item 1</x:String>
    <x:String>Item 2</x:String>
    <x:String>Item 3</x:String>
</ComboBox>

ฉันใช้วิธีนี้ - ผู้มีสิทธิเลือกตั้งเชิงลบสนใจที่จะอธิบายอย่างละเอียดหรือไม่? จริงอยู่ที่ฉันไม่ใช่ผู้เชี่ยวชาญ XAML แต่ก็ใช้ได้ผล
Robb Sadler

1
ถึงแม้ว่าผมจะไม่ได้เป็นผู้มีสิทธิเลือกตั้งลงผมคิดว่าคุณได้รับการโหวตลงเพราะไม่มีPlaceholderTextสถานที่ให้บริการในระดับSystem.Windows.ComboBox นี่เป็นคำถามเกี่ยวกับ WPF ไม่ใช่ WinForms
Sheridan

ผู้ชายคนนี้แปลก - ฉันรู้ว่าฉันกำลังทำงานกับแอป XAML และฉันรู้ว่าฉันเพิ่งค้นพบสิ่งนี้และเห็นว่ามันใช้งานได้ อาจมีส่วนขยายรวมอยู่ในโครงการหรือไม่ IDK - ฉันได้ดูตั้งแต่นั้นมาและแน่นอนว่าไม่มีตัวยึดตำแหน่งใน ComboBox ฉันไม่สามารถกลับไปที่โปรเจ็กต์ที่ฉันกำลังทำอยู่ - ลูกค้าเก่า ฮึ.
Robb Sadler

2
คุณไม่ผิด แต่นั่นไม่ใช่สำหรับ WPF UWP ComboBox มีสิ่งนี้โปรดดูหน้านี้: msdn.microsoft.com/en-us/library/windows/apps/…
laishiekai

0

ไม่ใช่แนวทางปฏิบัติที่ดีที่สุด. แต่ใช้ได้ผลดี ...

<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;
            }           
    }
}

0

ฉันเชื่อว่าลายน้ำตามที่กล่าวไว้ในโพสต์นี้จะใช้ได้ดีในกรณีนี้

มีรหัสเล็กน้อยที่จำเป็น แต่คุณสามารถใช้ซ้ำได้กับ combobox หรือ textbox (และแม้แต่รหัสผ่าน) ดังนั้นฉันจึงชอบวิธีนี้


0

ฉันใช้คลาส IsNullConverter ในโปรเจ็กต์ของฉันและมันใช้ได้ผลสำหรับฉัน นี่คือรหัสสำหรับมันใน c # สร้างโฟลเดอร์ชื่อ Converter และเพิ่มคลาสนี้ในโฟลเดอร์นั้นเนื่องจากทริกเกอร์ที่ใช้ไม่รองรับค่ามากกว่า 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>

0

// รหัส XAML

// รหัส ViewModel

    private CategoryModel _SelectedCategory;
    public CategoryModel SelectedCategory
    {
        get { return _SelectedCategory; }
        set
        {
            _SelectedCategory = value;
            OnPropertyChanged("SelectedCategory");
        }
    }

    private ObservableCollection<CategoryModel> _Categories;
    public ObservableCollection<CategoryModel> Categories
    {
        get { return _Categories; }
        set
        {
            _Categories = value;
            _Categories.Insert(0, new CategoryModel()
            {
                CategoryId = 0,
                CategoryName = " -- Select Category -- "
            });
            SelectedCategory = _Categories[0];
            OnPropertyChanged("Categories");

        }
    }

0

สายไปหน่อย แต่ ..

วิธีที่ง่ายกว่านั้นคือการเพิ่มรายการข้อมูลจำลองลงในรายการด้วยพารามิเตอร์ IsDummy = true และตรวจสอบให้แน่ใจว่าไม่ใช่ HitTestVisable และความสูงคือ 1 พิกเซล (โดยใช้ตัวแปลง) เพื่อที่จะไม่เห็น

กว่าแค่ลงทะเบียนกับ SelectionChanged และตั้งค่าดัชนีเป็นดัชนีรายการจำลอง

มันใช้งานได้อย่างมีเสน่ห์และด้วยวิธีนี้คุณจะไม่ยุ่งกับสไตล์และสีของ ComboBox หรือธีมแอปพลิเคชันของคุณ


0
InitializeComponent()
yourcombobox.text=" -- Select Team --";

รหัสข้างต้นแสดงให้เห็นถึงวิธีที่ง่ายที่สุดในการบรรลุเป้าหมาย หลังจากโหลดหน้าต่างแล้วให้ประกาศข้อความของคอมโบบ็อกซ์โดยใช้คุณสมบัติ. Text ของคอมโบบ็อกซ์ ซึ่งสามารถขยายไปยัง DatePicker, Textbox และตัวควบคุมอื่น ๆ ได้เช่นกัน


0

ฉันทำก่อนที่จะผูก combobox กับข้อมูลจากฐานข้อมูลใน codebehind แบบนี้ -

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

1
นี่เป็นการเพิ่มข้อความเป็นตัวเลือกในเมนูแบบเลื่อนลง นั่นไม่ใช่สิ่งที่ OP ขอ
Dean Friedland

มันเกี่ยวกับการเพิ่มข้อความเริ่มต้นและฉันก็ทำด้วยวิธีนี้
Atiq Baqi

0
  1. ติดป้ายที่ด้านบนของกล่องคอมโบ

  2. ผูกเนื้อหาของป้ายกำกับกับคุณสมบัติ combobox Text

  3. ตั้งค่าความทึบของกล่องคอมโบเป็นศูนย์ Opacity = 0

  4. เขียนข้อความเริ่มต้นในคุณสมบัติ combobox Text

          <ComboBox Name="cb"
            Text="--Select Team--" Opacity="0" 
            Height="40" Width="140" >
             <ComboBoxItem Content="Manchester United" />
             <ComboBoxItem Content="Lester" />
         </ComboBox>
     </Grid>

-2

ตั้งค่าแอตทริบิวต์ IsEditable เป็น true เท่านั้น

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

-3

ฉันรู้ว่ามันกึ่งเก่า แต่แล้ววิธีนี้:

<DataTemplate x:Key="italComboWM">
    <TextBlock FontSize="11" FontFamily="Segoe UI" FontStyle="Italic" Text="--Select an item--" />
</DataTemplate>

<ComboBox EmptySelectionBoxTemplate="{StaticResource italComboWM}" />

2
ComboBoxไม่มีEmptySelectionBoxTemplateทรัพย์สิน
Novitchi S
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.