Silverob中的Combobox显示值

时间:2010-10-12 12:00:59

标签: silverlight combobox

我有ComBoxBox和CheckBoxes项目。 当用户选中或取消选中复选框时,我希望所选值显示在以逗号分隔的ContentPresenter中。 目前我已经覆盖了ContentPresenter:

<ContentPresenter x:Name="ContentPresenter"
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
    Margin="{TemplateBinding Padding}"
    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
    ContentTemplate="{StaticResource SelectedOperationsText}"/>

默认情况下,ContentPresenter是ComboBox样式的一部分。 有关如何实现此功能的任何提示?

ComboBox ItemTemplate的实现如下:

<DataTemplate x:Key="ComboItemTemplate">
     <Grid HorizontalAlignment="Left">
         <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Text}"/>
     </Grid>
</DataTemplate>

3 个答案:

答案 0 :(得分:3)

此解决方案并不理想(例如,您可以为从组合框继承的控件创建自定义控件模板),但它可以正常工作。

  1. 的Xaml

    <my:MyComboBox Width="180" ItemsSource="{Binding TestItems}" Text="{Binding SelectedItemsText}">
        <my:MyComboBox.ItemTemplate>
            <DataTemplate>
                <Grid HorizontalAlignment="Left">
                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Text}"/>
                </Grid>
            </DataTemplate>
        </my:MyComboBox.ItemTemplate>
    </my:MyComboBox>
    
  2. 组合框的黑客:

    public class MyComboBox : ComboBox
    {
    private ContentPresenter selectedContent;
    
    
    public MyComboBox()
    {
        this.DefaultStyleKey = typeof(ComboBox);
    }
    
    
    public override void OnApplyTemplate()
    {
        this.selectedContent = this.GetTemplateChild("ContentPresenter") as ContentPresenter;
        this.RefreshContent();
        base.OnApplyTemplate();
        this.SelectionChanged += (s, e) =>
            {
                //Cancel selection
                this.SelectedItem = null;
                this.RefreshContent();
            };
    }
    
    
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    
    
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(MyComboBox), 
        new PropertyMetadata(null, new PropertyChangedCallback((s,e)=>((MyComboBox)s).RefreshContent())));
    
    
    private void RefreshContent()
    {
        if (this.selectedContent != null)
        {
            var tb = (TextBlock)this.selectedContent.Content;
            tb.Text = this.Text;
        }
    }
    }
    
  3. MainViewModel

    public class MainViewModel : INotifyPropertyChanged
    {
    public MainViewModel()
    {
        this.InitializeTestItems();
    }
    
    
    public void InitializeTestItems()
    {
        this.TestItems = new List<TestItemModel>{
                    new TestItemModel{IsChecked=true, Text="first"},
                    new TestItemModel{IsChecked=false, Text="second"},
                    new TestItemModel{IsChecked=false, Text="third"}};
        this.RefreshSelectedItemsText();
        foreach (var item in this.TestItems)
            item.CheckChanged += (s, e) => this.RefreshSelectedItemsText();
    }
    
    
    private void RefreshSelectedItemsText()
    {
        SelectedItemsText = string.Join(", ", this.TestItems.Where(ti => ti.IsChecked).Select(ti => ti.Text));
    }
    
    
    public List<TestItemModel> TestItems { get; set; }
    
    
    private string selectedItemsText;
    
    
    public string SelectedItemsText
    {
        get { return selectedItemsText; }
        set
        {
            selectedItemsText = value;
            OnPropertyChanged("SelectedItemsText");
        }
    }
    }
    
  4. 4.ItemViewModel

    public class TestItemModel
    {
        private bool isChecked;
    
        public bool IsChecked
        {
            get { return isChecked; }
            set 
            { 
                isChecked = value;
                if (CheckChanged != null)
                    CheckChanged(this, null);
            }
        }
    
        public string Text { get; set; }
    
        public event EventHandler<EventArgs> CheckChanged;
    }
    

答案 1 :(得分:0)

我不明白你对“ContentPresenter”的意思。

如果你想要一个包含选定项目列表的combox框,我可以解释我的儿子(不在SO中)是如何做到的:

他将一个带有ComboBox的网格后跟一个TextBlock。 ComboBox的ItemTemplate包含一个复选框,其中包含Checked和UnChecked事件的处理程序。在这些事件中,他根据复选框的选定状态重新计算TextBlock的Text属性。 这是XAML:

<Grid Name="LayoutRoot">
    <ComboBox ItemsSource="{Binding Path=SitesList}" Name="CBsites" DropDownOpened="ComboBox_DropDownOpened" DropDownClosed="ComboBox_DropDownClosed">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Path=Location}" Checked="SiteCheckBox_Checked" Unchecked="SiteCheckBox_Unchecked" />
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    <TextBlock Name="TXTselected" IsHitTestVisible="False" VerticalAlignment="Center" Margin="6,0,0,0" />
</Grid>

我认为没有TextBlock就可以做到。希望这可以让你朝着正确的方向前进。

答案 2 :(得分:0)

我在这里创建了一个codeplex项目:codeplex受到这篇博客的启发和其他一些项目,请检查并改进它等等。希望这或类似的东西能够找到它进入工具包的方式..

我更喜欢在绑定数据中不需要选择布尔值,所以我带来了一个可绑定的SelectedItems