Silverlight, как установить текстовый элемент элемента списка в корневую модель представления для представления, в котором он находится - PullRequest
1 голос
/ 12 августа 2011

В моем проекте у меня есть список, который использует табличку с данными.В этом шаблоне данных у меня есть кнопка.Когда список генерирует результаты, источник элемента для этого списка устанавливается в некоторый набор свойств, назовем его Results [0].

Проблема, с которой я сталкиваюсь, заключается в том, что когда я нажимаю кнопку для вызова метода из представленияМодель метод не может быть найден, потому что вызов ищет контекст списка, а не корневое представление.Я использую набор инструментов SimpleMVVM, который использует локатор, похожий на набор инструментов MVVMLight.

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

<UserControl.Resources>
    <formatter:HighlightConverter x:Key="FormatConverter" />
    <vml:SearchViewModel x:Key="vm" />
</UserControl.Resources>

, а затем кнопка содержит

<HyperlinkButton HorizontalAlignment="Left"
    Click="Button_Click"
    Content="{Binding Type}"
    Style="{StaticResource ListBoxtTitleHyperlink}">
 <i:Interaction.Triggers>
     <i:EventTrigger EventName="Click">
        <ei:CallMethodAction MethodName="GetDetailID" TargetObject="{Binding Source={StaticResource vm}}" />
     </i:EventTrigger>
 </i:Interaction.Triggers>
</HyperlinkButton>

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

Моя реализация может быть отключена.Так что я открыт для предложений. В таких ситуациях, как этот, каков наилучший подход, чтобы кнопка в шаблоне данных списка вызывала метод из модели представления и передавала параметры метода, полученные из выбранного элемента списка?

Чтобы увидеть полную реализацию кода, вы можете загрузить пример проекта из Папка SkyDrive

Обновление Я начинаю награду за этот вопрос, так как он поставил меня в тупик,Не стесняйтесь загружать пример проекта для справки.Для ясности цель этого вопроса состоит в том, чтобы узнать, как выполнить следующее 1. Выберите строку из списка 2. Событие selectionchanged установит для свойства текстовое значение, отображаемое в пользовательском интерфейсе (двусторонняя привязка RecordID с использованием Inotify 3. Нажмите накнопку в шаблоне элемента и вызов метода, сохраненного во ViewModel, с использованием триггеров взаимодействия и отображения в окне сообщения значения свойства RecordID.

Шаги I и 2. Выполнены. Я застрял в понимании того, как получитькнопка, которая является частью шаблона элемента списка, чтобы найти модель корневого представления и вызвать метод этой виртуальной машины без создания новой модели представления, которая бы сбросила все ранее сохраненные свойства.

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 16 августа 2011

Добавьте ресурс программно.Привязка StaticResource может пожаловаться во время разработки, но во время выполнения она должна просто работать.

UserControl имеет свойство Resources, которое возвращает ссылку на ResourceDictionary.Вы можете добавить ViewModel к этому, и эффект будет таким же, как в вашем примере Xaml, за исключением того, что вы можете повторно использовать существующую ViewModel.

Предполагая, что ваша инфраструктура MVVM уже заполнила DataContext UserControl с помощью ViewModel, тогдавы можете использовать код C #, аналогичный приведенному ниже, для настройки ресурса.

this.Resources.Add("vm", this.DataContext);

Если DataContext уже задан в конструкторе UserControl, он может пойти туда.В противном случае вам нужно будет найти хук, который вызывается позже в жизненном цикле UserControl.

Редактировать : Посмотрев на ваш код.Я бы предложил следующие модификации.

  1. Не устанавливайте ни DataContext, ни StaticResource "vm" в XAML.
  2. Используйте следующий код в качестве конструктора класса TemplateView.

Код :

public TemplateView()
{
    var templateViewModel = new TemplateViewModel();
    this.DataContext = templateViewModel;
    this.Resources.Add("vm", templateViewModel);
    InitializeComponent();
}

Здесь есть несколько ограничений, которые привели меня к этому решению.Во-первых, ресурс должен быть добавлен до InitializeComponent.Второе - это то, что templateViewModel должен быть доступен до того, как ресурс будет добавлен.

0 голосов
/ 16 августа 2011

Я разработчик WPF и не знаю наверняка, будет ли это работать в Silverlight, но я бы обычно изменил привязку на вашем целевом объекте на что-то вроде

 <ei:CallMethodAction MethodName="GetDetailID" TargetObject="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=ListBox, Mode=FindAncestor}}"/> 

По сути, просматривая дерево, пока оно не находит первого предка ListBox, а затем проверяя его свойство DataContext, которое, если я правильно прочитал ваш вопрос, является вашей ViewModel.

...