首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以编程方式为Silverlight ComboBox创建ComboBox?

以编程方式为Silverlight ComboBox创建ComboBox?
EN

Stack Overflow用户
提问于 2010-11-04 21:10:18
回答 4查看 4.1K关注 0票数 2

我正在尝试创建一个与ComboBoxes相关的混合行为。为了获得我想要的效果,ItemsPanel的ComboBox必须添加一个特定的元素。我不想在每个使用该行为的ComboBox中这样做,所以我希望行为能够以编程方式注入ItemsPanelTemplate。然而,我似乎想不出办法来做这件事。ItemsPanelTemplate似乎没有允许我设置可视树的属性/方法。WPF ItemsPanelTemplate有VisualTree,但Silverlight没有。

基本上,这个XAML的编程等效性是什么?

代码语言:javascript
复制
    <ComboBox>
        <ComboBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ComboBox.ItemsPanel>
    </ComboBox>

编辑:

好吧,显然这不是一个容易的问题,所以我开始了一个赏金,我将给出更多的背景,以防有其他的方法来解决这个问题。我想为Silverlight ComoboBox提供键盘支持。开箱即用,它只支持上下箭头,但我也希望它能够工作,这样当用户点击一个字母时,ComboBox跳到该字母的第一项,类似于ComboBoxes在浏览器或Windows应用程序中的工作方式。

我找到了这篇博客文章,这让我半途而废。根据该行为代码,ComboBox将根据字母输入更改选择。但是,当打开ComboBox时,它不起作用。根据这篇博客文章的说法,这样做的原因是,当打开ComboBox时,您现在正在与它的ItemsPanel而不是ComboBox本身交互。因此,根据这篇文章,我实际上需要向StackPanel中添加一个ItemsPanelTemplate,并订阅StackPanel的KeyDown事件,以便在打开ComboBox时采取行动。

因此,这就促使我提出了一个问题,那就是如何从行为中将StackPanel导入到ItemsPanelTemplate of a ComboBox中。如果这是不可能的,是否有其他办法使其发挥作用?是的,我知道我可以访问应用程序中的每个ComboBox并添加一个StackPanel和事件。但是我想通过一种行为来做到这一点,这样我就不必修改应用程序中的每个ComboBox,这样我就可以在应用程序中重用这个逻辑。

AnthonyWJones使用XamlReader给出的答案部分地帮助了我,因为我可以创建StackPanel并将其放入模板中。但是,为了订阅事件,我需要能够以编程的方式获得该SP。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-11-09 21:34:16

我认为,最好的方式-扩展组合框的功能不是通过行为,而是使用继承。因此,您可以创建自己的控件MyComboBox:ComboBox。为it创建样式-获取默认的ComboBox样式这里

然后写(按名字查找ScrollViewer ):

< ScrollViewer x:Name="ScrollViewer“BorderThickness=0”Padding="1“> < ItemsPresenter /> < /ScrollViewer >

< ScrollViewer x:Name="ScrollViewer“BorderThickness=0”Padding="1“> < StackPanel x:Name="StackPanel“>< ItemsPresenter /> < /StackPanel > < /ScrollViewer >

您可以在代码中获得这个StackPanel:

公共类MyComboBox: ComboBox{

代码语言:javascript
复制
    public CM()
    {
        DefaultStyleKey = typeof (MyComboBox);
    }
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        StackPanel stackPanel = (StackPanel)GetTemplateChild("StackPanel");
        stackPanel.KeyUp += (s, e) => { /*do something*/ };
    }

}

继承更有力量。它允许使用模板元素。如果您决定注入ItemsPanel,您必须理解这一点:

1)在注入面板上保留引用代码是不可能的。

2)为了获得注入面板的参考,该面板必须在某个存储区注册。

< ComboBox> < ComboBox.ItemsPanel> < ItemsPanelTemplate> < StackPanel> < i:Interaction.EventTriggers> < /i:EventTrigger> < /i:Interaction.EventTriggers> < /StackPanel> < /ItemsPanelTemplate> < /ComboBox.ItemsPanel> < /ComboBox>

祝好运!

票数 1
EN

Stack Overflow用户

发布于 2010-11-04 21:50:43

这应该能行。我已经向你展示了如何改变下面的方向。您可以添加其他SetValue调用来修改其他属性。

代码语言:javascript
复制
cb.ItemsPanel = new ItemsPanelTemplate();
var stackPanelFactory = new FrameworkElementFactory(typeof (StackPanel));
// Modify it like this:
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
// Set the root of the template to the stack panel factory:
cb.ItemsPanel.VisualTree = stackPanelFactory;

您可以在本文中找到更详细的信息:http://www.codeproject.com/KB/WPF/codeVsXAML.aspx

票数 6
EN

Stack Overflow用户

发布于 2010-11-04 23:02:04

您真正想要通过编程构建的是:-

代码语言:javascript
复制
<ItemsPanelTemplate>
    <StackPanel />
</ItemsPanelTemplate>

然后,您的行为将将其分配给附加到的ItemsPanel属性的ComboBox。目前,您的行为是纯代码,但没有办法纯粹在代码中创建上述内容。

由于这是Xaml的一小部分,最简单的方法是使用XamlReader:-

代码语言:javascript
复制
ItemsPanelTemplate itemsPanelTemplate = XamlReader.Load("<ItemsPanelTemplate><StackPanel /></ItemsPanelTemplate>");
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4101429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档