简体   繁体   中英

Find Listbox in DataTemplate inside ItemsControl

To create my own drophandler I need to get access to the listbox which is inside an ItemsControl.

XAML

 <ItemsControl ItemsSource="{Binding Days}" Name="myCalendar" Margin="200,75,0,0">         
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="6" Columns="7">                     
                </UniformGrid>                  
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <!-- ItemTemplate -->
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>

                    <TextBlock Text="{Binding Date}">
                    </TextBlock>

                    <ListBox Name="Scenes" ItemsSource="{Binding Scenes}" dd:DragDrop.IsDragSource="True" dd:DragDrop.IsDropTarget="True" dd:DragDrop.DropHandler="{Binding}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock>
                                     <Run Text="{Binding Path=SlugLine}"/>
                                </TextBlock>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

How do I get access or find the ListBox inside the ItemsControl from my ViewModel, not via code behind?

You absolutely do not want the VM knowing about the view. The whole point of MVVM is to decouple the view and the logic.

Instead handle the drop in the code-behind. Some people seem to believe that there should be no code-behind in MVVM, but it's absolutely fine as long as it's specific to the view, and there is no VM logic in there.

Imagine that you have hooked up a completely new view to your VM, say a console based text view. If your view logic remains intact with a completely new view, since it's all in the VM then you're fine. If you have logic in the code-behind that would disappear when you changed views, then you need that logic moved down to the VM.

Drag and drop is fine. You handle the drop in code-behind and then call the VM to do the logic associated with the drop, say via a bound command. If replacing the view with a text view, the drop could be CTRL-V instead, but the same VM command would be called to do the logic associated with the drop.

As mentioned, one way to call the VM from the code-behind would be to have a dependency property on the view that gets bound to a command in the VM, with your code-behind just invoking the command via the property.

A simpler way is to just cast the DataContext to your VM type and call a function directly. A lot of people dislike this since it couples the view to a VM type, but I see no issue with it at all. The view is already coupled to all bound properties on the VM anyway. VM's should be view agnostic, but the view NEEDS to know about the VM in order to be useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM