2013-05-19 4 views
0

В проекте я использую caliburn.micro в качестве рамки MVVM.Использование caliburn.micro с иерархической структурой вида просмотра

Теперь у меня есть несколько большая модель просмотра для представления основных деталей.

Это иерархически построенный.

Просто есть пример:

У меня есть ComputerView с ComputerViewModel. Здесь все отлично.

Сейчас этот ComputerViewModel содержит ObservableCollection<HardwareComponentViewModel>

Это HardwareViewModel не имеет View прикрепленную, это только там, чтобы сохранить данные на месте. Caliburn не настроен здесь Binding. (Я не могу использовать x:name, чтобы получить Binding)

До сих пор это не было проблемой, поскольку я мог использовать «нормальный» способ привязки. Теперь мне нужно добавить ActionMessage в сетку в HardwareComponentViewModel.

Для того, чтобы более ясно, что я имею в виду, вот это полный XAML, чтобы воспроизвести его

<UserControl x:Class="DemoApplication.Views.ComputersView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:cal="http://www.caliburnproject.org" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:s="clr-namespace:System;assembly=mscorlib" 
      d:DesignHeight="300" 
      d:DesignWidth="300" 
      mc:Ignorable="d"> 
    <Grid> 
     <Grid.Resources /> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="10*" /> 
      <RowDefinition Height="2*" /> 
      <RowDefinition Height="1*" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="1*" /> 
     </Grid.ColumnDefinitions> 

     <Border HorizontalAlignment="Stretch" 
       BorderBrush="Transparent" 
       BorderThickness="0"> 
      <ScrollViewer HorizontalContentAlignment="Stretch" 
          Background="Yellow" 
          BorderBrush="Transparent" 
          BorderThickness="0" 
          CanContentScroll="True" 
          HorizontalScrollBarVisibility="Auto" 
          VerticalScrollBarVisibility="Auto"> 
       <ListView x:Name="Computers" 
          HorizontalContentAlignment="Stretch" 
          Background="Red" 
          BorderThickness="0"> 
        <ListView.ItemTemplate> 
         <DataTemplate> 
          <Border Background="Transparent" 
            BorderBrush="Transparent" 
            BorderThickness="0"> 
           <ListView HorizontalContentAlignment="Stretch" 
              Background="Black" 
              ItemsSource="{Binding HardwareComponents}"> 
            <ListView.ItemTemplate> 
             <DataTemplate> 
              <Border Background="Aquamarine" 
                BorderBrush="DarkGray" 
                BorderThickness="1"> 
               <Grid Background="Lime" cal:Message.Attach="[Event Click] = [Action Expand($dataContext)]"> 
                <Grid.RowDefinitions> 
                 <RowDefinition Height="20" /> 
                </Grid.RowDefinitions> 
               </Grid> 
              </Border> 
             </DataTemplate> 
            </ListView.ItemTemplate> 
           </ListView> 
          </Border> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </ScrollViewer> 
     </Border> 
    </Grid> 
</UserControl> 

Update

1. Пытались cal:Bind.Model="{Binding}" на UserControl, но никакого эффекта Took them from this question here

2. В сетке я попробовал: cal:Message.Attach="[Event Click] = [Action Expand]", но не работает, либо

3. Я добавил Лесоразработку сейчас и получите

Конвенции Действия Не Прикладное: Нет действенный элемента для Expand.

Но я не знаю, что он пытается мне сказать. Возможно, никакое действие не может быть применено к Grid?

4. Теперь привязали его к кнопке внутри сетки, это работает. В качестве параметра передаю datacontext, который действительно является HardwareComponentViewModel, , но он барботируется самому внешнему ViewModel, где привязка настроена правильно (ComputerViewModel).

<Button cal:Message.Attach="[Event Click] = [Action Expand($dataContext)]"> 

Таким образом, вопрос: Что я должен сделать, чтобы получить Binding настроить правильно? Что мне нужно сделать, чтобы вызвать ActionMessages в HardwareComponentViewModel?

+0

Можете ли вы поделиться XAML вы пытались использовать, чтобы добавить ActionMessage к сетке? – T045T

+0

@ T045T Пожалуйста, посмотрите мой обновленный вопрос –

+0

@ T045T Если этого недостаточно XAML, пожалуйста, дайте мне знать. Вид действительно большой, поэтому я попытался сделать пример кратким. –

ответ

1

Наконец-то это заработало!

Событие, которое работает MouseDown, а не Click!

<Grid cal:Message.Attach="[Event MouseDown] = [Action Expand($dataContext)]" Background="Lime"> 

Спасибо вам большое за помощь!

Честно говоря, я не знаю, почему это работает, но он расширяется и разрушается как шарм :)

+0

Может быть, потому, что он на гриде, и, может быть, сетка не поддерживает 'Click' # (или что-то в этом роде!) - Рад, что вы его отсортировали, это такие проблемы, которые съедают дни по проекту: D – Charleh

+0

Большое спасибо Карле. Да, это заняло несколько часов ... –

1

Вы пробовали

cal:Action.TargetWithoutContext="{Binding DataContext}"

на вашей кнопки/сетки/там, где вам это нужно?Я ожидал бы, что цель действия будет текущей привязкой по умолчанию, но она может и не быть (не совсем точно, как CM проложит ее, может посмотреть на источник). Независимо от того, CM должен знать, какую цель попытаться связать действие с (VM) и из-за того, что он не связан стандартным способом CM, я предполагаю, что некоторая проводка не может быть выполнена автоматически, и вам необходимо явно привязать ее, используя выше код

+0

Попробовали это сейчас для сетки. Если я нажму на него, он больше не будет выбран правильно, но действие не будет вызвано (по крайней мере, я не вижу его в выводе Debug, поскольку я вижу его для кнопки, которую я вставил, чтобы опробовать, вызвано ли какое-либо действие). –

+0

Наверное, я делаю что-то не так. Не могли бы вы предоставить дополнительную информацию о том, что мне нужно сделать здесь? –

+0

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

1

Это скорее комментарий, действительно, но я помещаю это в ответ на правильное форматирование кода. Я использовал EventTrigger в подобной ситуации, и я помню, что это работает безотказно:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Click"> 
     <cal:ActionMessage MethodName="Expand" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

, где я есть в System.Windows.Interactivity пространство имен, определенное в XAML теге верхнего уровня через

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 

(Не конечно, если точная строка должна отличаться для приложения для настольных компьютеров)

Вы пробовали это сделать так?

+0

Вставьте это сразу после открытия . Кажется, не имеет никакого эффекта, возможно, мне нужно изменить некоторые части. (изменили ContactTapped на Expand, поскольку это имя метода, который я хочу вызвать). Должен ли я что-то делать с «Tap»? –

+0

Извините, код получен из мобильного приложения - я не уверен, что «Tap» также будет работать на рабочем столе, поэтому я изменил фрагмент кода, чтобы использовать «Click» - также, поскольку ваш метод не У меня есть параметр, я взял это :) – T045T

+0

Благодарим за обновление. Прямо сейчас я получаю «Action Convention Not Applied: без действительного элемента для Expand.' сначала, но позже я получаю« Action: Expand Availability update », что заставляет меня думать, что он правильно подключен. Но если я нажимаю на сетку, ничего не происходит, я пропускаю часть 'Invoking Action: Expand.' ... –

Смежные вопросы