Доступ к родительскому тексту данных в списке в Silverlight - PullRequest
24 голосов
/ 22 декабря 2008

В Silverlight 2 я использую пользовательский контроль, который наследует текст данных страницы, в которую он встроен. Этот текстовый текст содержит текст вопроса, тип вопроса и набор ответов. В пользовательском элементе управления есть список, который привязан к коллекции ответов. Как показано ниже:

<ListBox DataContext="{Binding}" x:Name="AnswerListBox" ItemContainerStyle="{StaticResource QuestionStyle}" Grid.Row="1" Width="Auto" Grid.Column="2" ItemsSource="{Binding Path=AnswerList}" BorderBrush="{x:Null}" />       

Этот список имеет связанный стиль для отображения ответов в виде переключателей или флажков (которые я хотел бы скрыть или показать в зависимости от типа вопроса) в виде:

<Style TargetType="ListBoxItem" x:Key="QuestionStyle">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">                      
                        <StackPanel Background="Transparent" >
                            <RadioButton Visibility="{Binding Path=QuestionType, Converter={StaticResource QuestionTypeConverter}, ConverterParameter='RadioButtonStyle'}" Height="auto" Margin="0,0,0,10"  IsChecked="{TemplateBinding IsSelected}" IsHitTestVisible="False" Content="{Binding Path=AnswerText}">
                            </RadioButton>
                            <CheckBox Visibility="{Binding Path=QuestionType, Converter={StaticResource QuestionTypeConverter}, ConverterParameter='CheckBoxStyle'}" Height="auto" Margin="0,0,0,10" Content="{Binding Path=AnswerText}">
                            </CheckBox>
                        </StackPanel>                                                
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Итак, мой вопрос заключается в следующем: как получить доступ к родительскому контексту данных, чтобы получить QuestionType (так как это свойство самого элемента данных datacontext, а не свойство элемента ответа в списке ответов)?

В качестве альтернативы, есть ли лучший способ динамического переключения стилей в xaml на основе значения привязки?

Ответы [ 4 ]

55 голосов
/ 11 января 2010

В Silverlight 3 и выше вы можете использовать привязку Элемент к элементу и указать элемент управления DataContext, а затем некоторые свойства в моем примере это свойство Threshold.

Итак, назовите ваш элемент управления (например, в моем примере это x: Name = "control")

<UserControl x:Class="SomeApp.Views.MainPageView" x:Name="control" >

, затем внутри этого элемента управления в вашем шаблоне ItemBox ItemTemplate вы можете получить доступ к родительскому DataContext следующим образом:

    <ListBox ItemsSource="{Binding Path=SomeItems}" >
        <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding ElementName=control, Path=DataContext.Threshold}"/>
            </StackPanel>
        </DataTemplate>
       </ListBox.ItemTemplate>         
       </ListBox>
1 голос
/ 19 июля 2010

Если вы пытаетесь сделать это с помощью DataForm, тот же метод, который показан Roboblob, не работает.

Этот вопрос может содержать некоторую полезную информацию

1 голос
/ 20 марта 2009

Одна из самых крутых вещей, которые вы можете сделать с помощью Silverlight, - это использовать атрибут Tag для хранения ссылки на объект, с которым он связан.

Сначала в вашем классе объявите свойство, подобное этому

public IMyObject Current 
{
  get {return this;}
}

Тогда на элемент управления, вызывающий событие, вы можете получить ссылку на объект

var fe= (FrameworkElement) sender;
var src = fe.Tag as IMyObject;

Итак, теперь, когда у меня есть объект, разумно, чтобы объект имел ссылку на своего родителя, чтобы вы связались с

Current.Parent.QuestionType
1 голос
/ 04 февраля 2009

Я только что боролся с подобной проблемой. Мой состоит из выпадающего списка, который отображается для каждого списка. DataContext верхнего уровня привязан к моей модели представления (MVVM) и выглядит следующим образом:

class ViewModel{
    ObservableCollection<ComboboxListItemType> DataForTheComboBoxList;
    ObservableCollection<MyDataType> DataForTheListBox;
    ...
}

Поскольку комбинированный список находится внутри ItemTemplate (= DataTemplate) для списка, DataContext для каждого элемента списка устанавливается на соответствующий элемент в DataForTheListBox, комбинированный блок больше не может видеть нужный DataForTheComboBoxList из DataContext верхнего уровня.

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

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

public partial class MyDataType
{
    private ObservableCollection<ComboboxListItemType> m_AllComboboxItems;
    public ObservableCollection<ComboboxListItemType> AllComboboxItems
    {
        get { return m_AllComboboxItems; }
        set
        {
            if (m_AllComboboxItems != value)
            {
                m_AllComboboxItems = value;
                RaisePropertyChanged("AllComboboxItems");
            }
        }
    }
}

Далее необходимо установить это свойство для каждого элемента в коллекции DataForTheListBox

// in ViewModel class
foreach(var x in this.DataForTheListBox)
{
    x.AllComboboxItems = this.DataForTheComboBoxList;
}

Затем вернитесь в свой XAML:

<DataTemplate x:Key="ListBoxItemTemplate">
    ...
    <Combobox
        ItemsSource="{Binding AllComboboxItems}"
        SelectedItem="{Binding CurrentBlah}"/>
</DataTemplate>

Не забывайте, что для того, чтобы в выпадающем списке правильно отображался текущий элемент, выбранный элемент должен ссылаться на фактический элемент в Источнике элементов в выпадающем списке. Если вы получаете данные из веб-службы, у которой есть идентификаторы или объекты, представляющие элемент для комбинированного списка, вы должны повторно сослаться на них, чтобы указать на фактическую коллекцию.

...