以编程方式为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>
然后,您的行为将其分配给它所连接的ComboBox
的ItemsPanel
属性。 目前,您的行为是纯代码,但无法在代码中纯粹创建上述代码。
由于这是Xaml的一小部分,最简单的方法是使用XamlReader: -
ItemsPanelTemplate itemsPanelTemplate = XamlReader.Load("<ItemsPanelTemplate><StackPanel /></ItemsPanelTemplate>");
链接地址: http://www.djcxy.com/p/41255.html
上一篇: Programatically create ItemsPanelTemplate for Silverlight ComboBox?
下一篇: Silverlight ComboBox