Отображаемое значение в выпадающем списке в Silverlight - PullRequest
3 голосов
/ 12 октября 2010

У меня есть ComboBox с 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 ]

3 голосов
/ 12 октября 2010

Это решение не идеально (например, вы можете создать собственный шаблон элемента управления для элемента управления, унаследованного от выпадающего списка), но оно работает.

  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 голосов
/ 30 марта 2012

Я создал проект codeplex здесь: codeplex , вдохновленный этим блогом и рядом других, пожалуйста, проверьте его и улучшите его и т. Д. Надеемся, что это или что-то подобное найдет свой путь в инструментарий ...

Я предпочитаю не использовать логическое значение выбора в связанных данных, поэтому я привел привязываемые SelectedItems

0 голосов
/ 12 октября 2010

Я не понял, что вы имели в виду под "ContentPresenter".

Если вам нужно поле со списком, со списком выбранных элементов в качестве текста, я могу объяснить, как мой сын (которого нет в SO) сделал это:

Он поставил сетку с ComboBox, а затем TextBlock. ItemTemplate ComboBox включает в себя флажок с обработчиком для событий Checked и UnChecked. В этих событиях он пересчитал свойство Text элемента TextBlock, основываясь на выбранном состоянии флажков. Вот 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. Надеюсь, это может привести вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...