【问题标题】:'Default' text for templated combo box模板组合框的“默认”文本
【发布时间】:2010-02-26 17:17:49
【问题描述】:

我有一个基于数据模板的组合框,其中包含如下复选框:

    <ComboBox x:Name="cboComplex" Text="Select days...">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Path=IsSelected}" Width="20"/>
                    <TextBlock Text="{Binding DayOfWeek}" Width="100" />
                 </StackPanel>
            </DataTemplate>

        </ComboBox.ItemTemplate>
    </ComboBox>

我遇到的问题是我希望组合框显示“选择日期...”,然后在单击时显示列表。不幸的是,设置 Text 属性似乎没有效果。任何想法或帮助将不胜感激。

提前致谢!

西格

【问题讨论】:

    标签: wpf combobox datatemplate


    【解决方案1】:

    当 ComboBox 可编辑时使用 Text 属性。您可以通过向 ControlTemplate 添加一个元素来设置默认的“选择”类型消息,该元素仅在没有选择时显示然后消失。使用此方法,您无需担心修改您的集合或让用户尝试从列表中选择“选择”消息,因为它不是列表的一部分。我建议使用标签在每个实例或样式中设置您的消息,然后添加一个新的 TextBlock 以将其显示到默认模板中:

    <TextBlock x:Name="SelectMessage" HorizontalAlignment="Left" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag}" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" Visibility="Collapsed"/>
    

    那么你可以这样使用它:

    <ComboBox ItemsSource="{Binding MyList}" Template="{StaticResource ComboBoxMessageTemplate}" Tag="Select days..."/>
    

    这是默认 Aero ComboBox 模板的完整 Blend 生成副本,其中包含更改。您还需要主题命名空间 (xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero") 和对 PresentationFramework.Aero 程序集的引用:

    <Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry>
    <Style x:Key="ComboBoxReadonlyToggleButton" TargetType="{x:Type ToggleButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="ClickMode" Value="Press"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}">
                        <Grid HorizontalAlignment="Right" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
                            <Path x:Name="Arrow" Fill="Black" HorizontalAlignment="Center" Margin="3,1,0,0" VerticalAlignment="Center" Data="{StaticResource DownArrowGeometry}"/>
                        </Grid>
                    </Microsoft_Windows_Themes:ButtonChrome>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="true">
                            <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <ControlTemplate x:Key="ComboBoxMessageTemplate" TargetType="{x:Type ComboBox}">
        <Grid x:Name="MainGrid" SnapsToDevicePixels="true">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
            </Grid.ColumnDefinitions>
            <Popup x:Name="PART_Popup" Margin="1" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Grid.ColumnSpan="2">
                <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}" Color="Transparent">
                    <Border x:Name="DropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
                        <ScrollViewer CanContentScroll="true">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.DirectionalNavigation="Contained"/>
                        </ScrollViewer>
                    </Border>
                </Microsoft_Windows_Themes:SystemDropShadowChrome>
            </Popup>
            <ToggleButton Style="{StaticResource ComboBoxReadonlyToggleButton}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" IsHitTestVisible="false" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
            <TextBlock x:Name="SelectMessage" HorizontalAlignment="Left" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag}" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" Visibility="Collapsed"/>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="SelectedItem" Value="{x:Null}">
                <Setter Property="Visibility" TargetName="SelectMessage" Value="Visible"/>
            </Trigger>
            <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
                <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
                <Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
            </Trigger>
            <Trigger Property="HasItems" Value="false">
                <Setter Property="Height" TargetName="DropDownBorder" Value="95"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                <Setter Property="Background" Value="#FFF4F4F4"/>
            </Trigger>
            <Trigger Property="IsGrouping" Value="true">
                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    【讨论】:

    • +1 谢谢,很好的答案。只需添加到 TextBlock 的一件事就是 HitTestVisible="False"。
    • 不错的解决方法,纯 XAML 和无 Text 属性滥用,全面取胜 :)
    【解决方案2】:

    在组合框中显示默认文本

     <ComboBox Height="23" HorizontalAlignment="Left" Margin="180,18,0,0" Name="cmbExportData" VerticalAlignment="Top" Width="148" ItemsSource="{Binding}" Text="-- Select Value --" AllowDrop="False" IsEditable="True" IsManipulationEnabled="False" IsReadOnly="True" />
    
    • 设置组合框的文本属性
    • 标记为IsEditable = true
    • 标记为IsReadOnly = true

    【讨论】:

      【解决方案3】:

      您必须在基础集合类中创建一个新项目,其值为“Select Days...”,索引 [0] 并将所选索引更改为 0。

          <ComboBox x:Name="cboComplex" SelectedIndex="0">
              <ComboBox.ItemTemplate>
                  <DataTemplate>
                      <StackPanel Orientation="Horizontal">
                          <CheckBox IsChecked="{Binding Path=IsSelected}" Width="20"/>
                          <TextBlock Text="{Binding DayOfWeek}" Width="100" />
                       </StackPanel>
                  </DataTemplate>
      
              </ComboBox.ItemTemplate>
          </ComboBox>
      

      或者另一种选择是在其上放置一个带有文本“Select Days...”的标签,然后监听 OnSelectionChanged 事件,如果 SelectedIndex 不是 -1,则将标签可见性更改为 false,否则为真。例如

          private void MyListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
          {
              if (MyListBox.SelectedIndex >= 0)
              {
                  MyListBoxInitialLabel.Visibility = Visibility.Hidden;
              }
              else
              {
                  MyListBoxInitialLabel.Visibility = Visibility.Visible;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-14
        • 2012-04-07
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多