以编程方式为Silverlight组合框创建ItemsPanelTemplate?

我正在尝试创建与ComboBoxes相关的Blend行为。 为了得到我想要的效果,ComboBox的ItemsPanel必须添加一个特定的元素。 我不想在每个使用行为的ComboBox中都这样做,所以我希望行为能够以编程方式注入ItemsPanelTemplate。 但是,我似乎无法找到办法做到这一点。 ItemsPanelTemplate似乎没有让我设置可视化树的属性/方法。 WPF ItemsPanelTemplate具有VisualTree,但Silverlight没有。

基本上,这个XAML的编程等价物是什么?

    <ComboBox>
        <ComboBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ComboBox.ItemsPanel>
    </ComboBox>

编辑:
好吧显然这不是一个简单的问题,所以我开始了一个赏金,我会给出更多的背景,以便有另一种方式可以解决这个问题。 我想为Silverlight ComoboBox提供键盘支持。 开箱即用,它只支持向上和向下箭头,但我也希望它能够工作,以便当用户点击一个字母时,ComboBox跳转到该字母的第一项,类似于ComboBoxes在浏览器或Windows应用程序中的工作方式。

我发现了这篇博客文章,这让我感到一半。 修改该行为代码,组合框将根据字母输入更改选择。 但是,打开组合框时它不起作用。 根据这篇博文的理由是,当ComboBox被打开时,你现在正在与它的ItemsPanel进行交互,而不是ComboBox本身。 所以根据这篇文章,我实际上需要添加一个StackPanel到ItemsPanelTemplate并订阅StackPanel的KeyDown事件,以便在ComboBox打开时执行操作。

所以这是什么促使我的问题如何从一个行为中获取一个StackPanel到一个ComboBox的ItemsPanelTemplate中。 如果这是不可能的,是否有其他方法来实现这个工作? 是的,我知道我可以去应用程序中的每个ComboBox并添加一个StackPanel和事件。 但我希望通过一种行为来实现这一点,这样我就不必修改应用程序中的每个ComboBox,因此我可以在应用程序中重复使用该逻辑。

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


我认为,对你来说最好的方式 - 不是通过行为扩展组合框功能,而是使用继承。 所以,你可以创建自己的控件MyComboBox: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:组合框{

    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 EventName="Loaded">

                  < RegisterMyInstanceInAccessibleFromCodePlaceAction/>

               < /i:EventTrigger>

             < /i:Interaction.EventTriggers>

          < /StackPanel>

       < /ItemsPanelTemplate>

   < /ComboBox.ItemsPanel>

</ ComboBox>

祝你好运!


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

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


你实际上想要以编程方式构建的是:

<ItemsPanelTemplate>
    <StackPanel />
</ItemsPanelTemplate>

然后,您的行为将其分配给它所连接的ComboBoxItemsPanel属性。 目前,您的行为是纯代码,但无法在代码中纯粹创建上述代码。

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

ItemsPanelTemplate itemsPanelTemplate = XamlReader.Load("<ItemsPanelTemplate><StackPanel /></ItemsPanelTemplate>");
链接地址: http://www.djcxy.com/p/41255.html

上一篇: Programatically create ItemsPanelTemplate for Silverlight ComboBox?

下一篇: Silverlight ComboBox