我正在尝试创建一个与ComboBoxes相关的混合行为。为了获得我想要的效果,ItemsPanel的ComboBox必须添加一个特定的元素。我不想在每个使用该行为的ComboBox中这样做,所以我希望行为能够以编程方式注入ItemsPanelTemplate。然而,我似乎想不出办法来做这件事。ItemsPanelTemplate似乎没有允许我设置可视树的属性/方法。WPF ItemsPanelTemplate有VisualTree,但Silverlight没有。
基本上,这个XAML的编程等效性是什么?
<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。
发布于 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{
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>
祝好运!
发布于 2010-11-04 21:50:43
这应该能行。我已经向你展示了如何改变下面的方向。您可以添加其他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
发布于 2010-11-04 23:02:04
您真正想要通过编程构建的是:-
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>然后,您的行为将将其分配给附加到的ItemsPanel属性的ComboBox。目前,您的行为是纯代码,但没有办法纯粹在代码中创建上述内容。
由于这是Xaml的一小部分,最简单的方法是使用XamlReader:-
ItemsPanelTemplate itemsPanelTemplate = XamlReader.Load("<ItemsPanelTemplate><StackPanel /></ItemsPanelTemplate>");https://stackoverflow.com/questions/4101429
复制相似问题