2010-10-12 101 views
3

我有组合框与项目的复选框。 当用户选中或取消选中框时,我希望将所选值显示在用逗号分隔的ContentPresenter中。 在我已重写ContentPresenter的时刻:Silverlight中的组合框显示值

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

ContentPresenter是默认的组合框风格的一部分。 有关如何实现此功能的任何提示?

组合框的ItemTemplate实现这样的:

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

回答

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.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; 
} 
+0

非常感谢您!非常有用。我已经有ItemTemplate,也有一个依赖属性,但不知道如何处理在combobox的contentpresenter中显示的文本信息。奇怪的是,Silverlight组合框没有办法通过属性来覆盖这个。 – Dmitry 2010-10-13 10:10:33

0

我不明白你的 “ContentPresenter” 是什么意思。

如果你想有一个COMBOX框,选择的项目作为其文本列表,我可以解释我的儿子(谁在SO不)是如何做到的:

他把网格组合框后跟一个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的。希望这可以让你在正确的方向。

+0

ContentPresenter是组合框风格的一部分默认 – Dmitry 2010-10-12 12:42:36

0

我创建了一个CodePlex项目位置:codeplex通过这个博客和许多其他的启发,请检查出来,并提高其等希望这或类似的东西会发现它的方式进入该工具包...

我不想在需要绑定的数据选择布尔,所以我带来了可绑定SelectedItems