IT 专业人士的资源 > 论坛主页 > Web 技术 论坛 > Silverlight 技术 > 怎么让 Combobox 在展开的时候 让文本框里的内容继续显示选中项的内容而不是空白?
提出问题提出问题
 

已答复怎么让 Combobox 在展开的时候 让文本框里的内容继续显示选中项的内容而不是空白?

答案

  • 2009年11月4日 2:50Allen Chen - MSFTMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复
    你好,
    由于内置的控件把代码写死了:
    private void OnIsDropDownOpenChanged(bool isDropDownOpen)
    {
        if (isDropDownOpen)
        {
            if (this.ElementPopup != null)
            {
                this.ElementPopup.IsOpen = true;
            }
            if (this.ElementDropDownToggle != null)
            {
                this.ElementDropDownToggle.IsChecked = true;
            }
            this.SetContentPresenter((base.SelectedItem is FrameworkElement) ? -1 : base.SelectedIndex);
            this.OnDropDownOpened(EventArgs.Empty);
        }
    ...
    可以看到当DropDownOpen的时候会调用this.SetContentPresenter((base.SelectedItem is FrameworkElement) ? -1 : base.SelectedIndex);
    大部分情况下SelectedItem 就是源自FrameworkElement所以等于调用了this.SetContentPresenter(-1).
    再看看SetContentPresenter方法:

    private void SetContentPresenter(int index)
    {
     ...      
       if (index == -1)
        {
            if (this.ElementContentPresenter != null)
            {
                this.ElementContentPresenter.Content = this._emptyContent;
                this.ElementContentPresenter.ContentTemplate = null;
            }
            this.SelectionBoxItem = null;
            this.SelectionBoxItemTemplate = null;
        }
    ...
    index为-1时会把ElementContentPresenter.Content 设置为_emptyContent. ElementContentPresenter为ComboBox模板内的ContentPresenter, _emptyContent则是ComboBox模板内ContentPresenter的最初的Content:

     <Border x:Name="ContentPresenterBorder">
                                <Grid>
                                    <ToggleButton x:Name="DropDownToggle" HorizontalAlignment="Stretch" Margin="0" Style="{StaticResource comboToggleStyle}" VerticalAlignment="Stretch" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalContentAlignment="Right">
                                        <Path x:Name="BtnArrow" Stretch="Uniform" Height="4" HorizontalAlignment="Right" Margin="0,0,6,0" Width="8" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z ">
                                            <Path.Fill>
                                                <SolidColorBrush x:Name="BtnArrowColor" Color="#FF333333"/>
                                            </Path.Fill>
                                        </Path>
                                    </ToggleButton>
                                    <ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                        <TextBlock/>
                                    </ContentPresenter>
                                </Grid>
                            </Border>

    解决办法就是在 this.SetContentPresenter调用之后,再次设置ContentPresenter的Content.我写了一个简单的控件,你可以参考下如何做到:

    http://cid-2fa13ebc6cc8e80f.skydrive.live.com/self.aspx/Public/MyComboBox.zip

    测试代码:

     

     

    <c:MyComboBox Width="200" Height="50">

     

     

    <ComboBoxItem Content="a"/>

     

     

    <ComboBoxItem Content="b"/>

     

     

    <ComboBoxItem Content="c"/>

     

     

    </c:MyComboBox>



    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework http://cfx.codeplex.com/! If you have any feedback, please tell us.

全部回复

  • 2009年11月4日 2:50Allen Chen - MSFTMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复
    你好,
    由于内置的控件把代码写死了:
    private void OnIsDropDownOpenChanged(bool isDropDownOpen)
    {
        if (isDropDownOpen)
        {
            if (this.ElementPopup != null)
            {
                this.ElementPopup.IsOpen = true;
            }
            if (this.ElementDropDownToggle != null)
            {
                this.ElementDropDownToggle.IsChecked = true;
            }
            this.SetContentPresenter((base.SelectedItem is FrameworkElement) ? -1 : base.SelectedIndex);
            this.OnDropDownOpened(EventArgs.Empty);
        }
    ...
    可以看到当DropDownOpen的时候会调用this.SetContentPresenter((base.SelectedItem is FrameworkElement) ? -1 : base.SelectedIndex);
    大部分情况下SelectedItem 就是源自FrameworkElement所以等于调用了this.SetContentPresenter(-1).
    再看看SetContentPresenter方法:

    private void SetContentPresenter(int index)
    {
     ...      
       if (index == -1)
        {
            if (this.ElementContentPresenter != null)
            {
                this.ElementContentPresenter.Content = this._emptyContent;
                this.ElementContentPresenter.ContentTemplate = null;
            }
            this.SelectionBoxItem = null;
            this.SelectionBoxItemTemplate = null;
        }
    ...
    index为-1时会把ElementContentPresenter.Content 设置为_emptyContent. ElementContentPresenter为ComboBox模板内的ContentPresenter, _emptyContent则是ComboBox模板内ContentPresenter的最初的Content:

     <Border x:Name="ContentPresenterBorder">
                                <Grid>
                                    <ToggleButton x:Name="DropDownToggle" HorizontalAlignment="Stretch" Margin="0" Style="{StaticResource comboToggleStyle}" VerticalAlignment="Stretch" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalContentAlignment="Right">
                                        <Path x:Name="BtnArrow" Stretch="Uniform" Height="4" HorizontalAlignment="Right" Margin="0,0,6,0" Width="8" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z ">
                                            <Path.Fill>
                                                <SolidColorBrush x:Name="BtnArrowColor" Color="#FF333333"/>
                                            </Path.Fill>
                                        </Path>
                                    </ToggleButton>
                                    <ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                        <TextBlock/>
                                    </ContentPresenter>
                                </Grid>
                            </Border>

    解决办法就是在 this.SetContentPresenter调用之后,再次设置ContentPresenter的Content.我写了一个简单的控件,你可以参考下如何做到:

    http://cid-2fa13ebc6cc8e80f.skydrive.live.com/self.aspx/Public/MyComboBox.zip

    测试代码:

     

     

    <c:MyComboBox Width="200" Height="50">

     

     

    <ComboBoxItem Content="a"/>

     

     

    <ComboBoxItem Content="b"/>

     

     

    <ComboBoxItem Content="c"/>

     

     

    </c:MyComboBox>



    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework http://cfx.codeplex.com/! If you have any feedback, please tell us.
  • 2009年11月4日 5:28zhang xiaolei 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    辛苦了  多谢!     其实我就是想问 在不重新写控件的情况下 Combobox 本身能不能解决问题   看来是不能了.