Sime question: Master Detail on a screen?

Apr 26, 2011 at 1:23 PM

 have a small utility application where I try out Caliburn Micro now for the first time.

One screen I have - the main appluication shows different screens in a tab interface, which explain small parts of a larger application.

On the screen Iam asupposed to ahve topics on the right - actualyl class names - and on the left an example of the usage of the class (generaed by reflection). Soudns stupid, but this explains how the XMML Form for some data trransfer classes looks without writing tons of manual documentation - for people supposed to geenrate thee XML in excel scripts.

Anyhow, the "screen" I talk of inherits "Screen":

public class ApiHelperViewMopel : Screen

Techncially this is upposed to be an eay master detail. How do Iimplement it? I have a BindableCOllection<Item> (yes, the base class of dataitems is Item). Bu how do I hadle the detail view? Any simple example? Advice?

Regards

Apr 26, 2011 at 1:43 PM

Look at this post, I got the same intention.

http://caliburnmicro.codeplex.com/discussions/252519

Does it help?

Apr 26, 2011 at 1:59 PM

Sort ofm, jsut I udon't use silverlight and there is no answer for your post either ;(

Apr 26, 2011 at 2:00 PM

Sorry, read it again. So you pbasically expose a CONDUCTOR? Not a bindable list? And then use that to drive your views?

Coordinator
Apr 26, 2011 at 2:50 PM
Edited Apr 26, 2011 at 2:51 PM
 public class ApiHelperViewModel : Conductor<Item>.Collection.OneActive{

   protected override OnInitialize(){

      //add your item instances to the Items collection of the conductor

      ActivateItem(Items[0]);

   }

}

This will create a ViewModel with an Items collection of type Item and an ActiveItem of type Item. The conductor is the master list with the ActiveItem being the currently selected item to show the detail for. Now you could create a simple view for the conductor like this:

<DockPanel>
   <ListBox x:Name="Items"
                 DisplayMemberPath="ClassName"
                 DockPanel.Dock="Left" />
   <ContentControl x:Name="ActiveItem" />
</DockPanel>

This will create a list of all the items. Selection will be synchronized with the conductor which will cause the content control to show the ActiveItem. Then, all you need to do is create a details view for the Item.

Apr 26, 2011 at 3:28 PM

How do I do that if I do not want to show a detail view? Or: the items are actually entities defined in another namespace in another dll that are "non visual" (data transfer opbjects).

The view is supposed to take an item, run it through a converter to a string and show that in a textbox. The converter will use reflection to find out which subclass of item is in every element an then find the properties and generate the proper description.

Obviously:

* I dont want to ahve aview per sub-item.

* Actually I am not sure I even want a sub-view. Iam totally comfortable with the the content being basically a textbox (DataTemplate) and using a converter.

How do I prced now? I just put aboce in and the ContentControl is empty - assumingly because of missing views.

Coordinator
Apr 26, 2011 at 4:18 PM

Just provide a DataTemplate for the content control. Put a TextBox in there and add a value converter to do whatever you want. I'm not sure I understand exactly what you are trying to do, but that's my best guess.

Apr 26, 2011 at 4:44 PM

Honestly, I think that you just need a DataTemplate... note, by the way, that you will always have a view for each sub-item... what you don't have is a view *type* for each item.

Apr 27, 2011 at 9:30 AM

You may be right with this. Still, it works now partially - it does not update when the listbox changes.

* The "screen" is still a screen but has a property of the conductor:

public Conductor<Item>.Collection.OneActive

Items

The view then has:

<ListBox DockPanel.Dock="Right" x:Name="Items" ItemsSource="{Binding Path=Items.Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Path=TypeName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ContentControl x:Name="ActiveItem" Content="{Binding Path=Items.ActiveItem}" />

The problem: the OneActive part of the condutor is not reactiong. I have two different Item instances there at the moment, but something is broken in the update of the ContentControl. As in: whatever I click around on the ListBox, the ContentControl does not update at all. What am I missing?

Apr 27, 2011 at 9:37 AM

Are you sure the above code does change the ActiveItem on selection changed?

If not, you can do it explicitly:

<ListBox DockPanel.Dock="Right"
         x:Name="Items"
         ItemsSource="{Binding Path=Items.Items}"
         SelectedItem="{Binding Path=Items.ActiveItem, Mode=TwoWay}">
      <ListBox.ItemTemplate>
            <DataTemplate>
                  <Label Content="{Binding Path=TypeName}" />
            </DataTemplate>
       </ListBox.ItemTemplate>
</ListBox>
<ContentControl x:Name="ActiveItem"
                Content="{Binding Path=Items.ActiveItem, Mode=OneWay}" />
Apr 27, 2011 at 10:00 AM

Actually that was it - the ListBox did NOT update the Conductor. I thought that would be wired up automatically ;) Quite obviously it is not.

Works now, switches when I select another active item.