【问题标题】:Contained ViewModel Events in Caliburn Micro Not FiringCaliburn Micro 中包含的 ViewModel 事件未触发
【发布时间】:2017-04-14 20:36:57
【问题描述】:

我有一个 ExplorerWindow V/VM UserControl,其中包含另一个 FileSystemTree V/VM UserControl。

这些控件都不包含在 MainVM 维护的 Screens 集合中,因为 ExplorerWindowView 显示为模式弹出窗口。

在 ExplorerWindowView 上触发事件;但是,尚不清楚附加事件如何或为什么没有在包含的 FileSystemView 上触发。

ExplorerWindowView

<UserControl x:Class="KTronInd.Wpf.ControlLibrary.FileExplorer.Views.ExplorerWindowView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:view="clr-namespace:KTronInd.Wpf.ControlLibrary.FileExplorer.Views"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         x:Name="Explorer"
         xmlns:cal="http://www.caliburnproject.org"
         cal:Message.Attach="[Event Loaded]=[Action ExplorerLoaded($eventArgs)]"
         mc:Ignorable="d" 
         d:DesignHeight="300"
         d:DesignWidth="500">


<Grid x:Name="OuterGrid" 
      Width="800" 
      Height="400">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition  />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="5" />
    </Grid.RowDefinitions>

    <!--Display the DirectoryTree on the left side of the grid DataContext="{Binding Explorer, Source={StaticResource Locator}}" -->
    <view:FileSystemTreeView Grid.Column="0"
                             DataContext="{Binding FileTreeVM}"
                             Grid.Row="0"  
                             Visibility="Visible"/>

    <!-- pane splitter-->
    <GridSplitter Grid.Column="0" 
                  Grid.Row="0" 
                  HorizontalAlignment="Right" 
                  Width="3" 
                  Background="Gray" 
                  Visibility="Visible" />

    <!--Display the File and Directory Selector on the right side of the grid DataContext="{Binding Explorer, Source={StaticResource Locator}}" -->
    <ScrollViewer Grid.Column="1" Grid.Row="0" >
        <view:DirectoryViewerView />
    </ScrollViewer>

</Grid>

...和 ​​ExplorerWindowViewModel

[Export( typeof( IScreen ) ), PartCreationPolicy( CreationPolicy.NonShared )]
public class ExplorerWindowViewModel : Screen, IHandle<ModelEvent>
{
[ImportingConstructor]
public ExplorerWindowViewModel( IEventAggregator events )
{
    m_Events = events;
    FileTreeVM = new FileSystemTreeViewModel( this , m_Events );
    //FileTreeVM.ConductWith( this ); 
.
.
}
.
.
public FileSystemTreeViewModel FileTreeVM
    {
        get
        {
            return _fileTreeVM;
        }
        set
        {
            _fileTreeVM = value;
            NotifyOfPropertyChange( () => FileTreeVM );
        }
    }   
}

这是文件系统树视图

UserControl x:Class="KTronInd.Wpf.ControlLibrary.FileExplorer.Views.FileSystemTreeView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:cal="http://www.caliburnproject.org"
         xmlns:vm="clr-namespace:KTronInd.Wpf.ControlLibrary.FileExplorer.ViewModels"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" >

<UserControl.Resources>

    <vm:GetFileSysemInformationConverter x:Key="getFileSysemInformationConverter"/>

    <HierarchicalDataTemplate DataType = "{ x:Type vm:DirInfo }" 
                              ItemsSource = "{ Binding Converter={ StaticResource getFileSysemInformationConverter } }" >

        <StackPanel Orientation="Horizontal">

            <Image Width="20" 
                   Height="20" 
                   Stretch="Fill" 
                   x:Name="img" />

            <TextBlock Text="{ Binding Name }" 
                       Margin="5,0,0,0" />

        </StackPanel>

        <!-- The HDT triggers bind the directory to an image representing the object type. -->
        <HierarchicalDataTemplate.Triggers>
            <!-- My Computer -->
            <DataTrigger Binding="{ Binding Path = DirType }" 
                         Value="0">

                <Setter Property="Image.Source" 
                        TargetName="img" 
                        Value="..\Images\MyComputer.jpg" />

            </DataTrigger>

            <!-- A disk drive -->
            <DataTrigger Binding="{ Binding Path = DirType }" 
                         Value="1">

                <Setter Property="Image.Source" 
                        TargetName="img" 
                        Value="..\images\diskdrive.png" />

            </DataTrigger>

            <!-- A folder -->
            <DataTrigger Binding="{ Binding Path = DirType }" 
                         Value="2">

                <Setter Property="Image.Source" 
                        TargetName="img"
                        Value="..\images\folder.png" />

            </DataTrigger>

        </HierarchicalDataTemplate.Triggers>

    </HierarchicalDataTemplate>

    <!-- TreeViewItem property setters -->
    <Style TargetType="TreeViewItem">
        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>

</UserControl.Resources>

<Grid Background="Beige" >

    <TreeView x:Name="DirectoryTree"  
              ItemsSource="{Binding Path = FileTreeVM.SystemDirectorySource}"
              cal:Message.Attach="[Event Loaded]=[Action FSTViewLoaded($eventArgs)]"
              BorderThickness="0"
              VerticalAlignment="Stretch"
              HorizontalAlignment="Stretch" 
              Width="300" >

    </TreeView>
</Grid>

最后是 FileSystemTreeViewModel

[Export( typeof( IScreen ) ), PartCreationPolicy( CreationPolicy.NonShared )]
public class FileSystemTreeViewModel : Screen , IHandle<ModelEvent>
{
    [ImportingConstructor]
    public FileSystemTreeViewModel( ExplorerWindowViewModel evm , IEventAggregator events )
    {
        m_Events = events;
        InitVM( evm );
    }    
}

如何让事件触发:ExplorerWindowView 中包含的 FileSystemTreeView 或 FileSystemTreeView 内的 TreeView 控件?

提前谢谢...

【问题讨论】:

    标签: c# wpf xaml mvvm caliburn.micro


    【解决方案1】:

    您好 hyland Computer Systems,您是否检查过您的视图模型是否为实际模型?我已经在类似的情况下遇到了问题,我还将我的 vm 声明为 datacontext(或 Ressource,不再有任何线索),并且在我引发 notifypropetychanged 或 -changed 事件时没有任何反应。问题是,我喂了“错误的”虚拟机。我有一个虚拟机,它是由视图创建的,另一个是每次注入创建的。注射的那个是我喂的那个。所以我只是再次覆盖了我的视图的数据上下文,然后我们开始->一切正常。

    【讨论】:

    • 嗨,Alexander:我实际上从 DI 注入的 Screens 集合中得到了一个,并用它来创建对话框。还是一样的结果。感谢您的回复。
    【解决方案2】:

    cal:Message.Attach="[Event Loaded]=[Action FSTViewLoaded($eventArgs)]"你真的定义了这个动作吗?

    编辑: 澄清定义..您的视图模型中是否有一个具有该名称的方法,该方法将EventArgs 作为该方法的参数?

    应用运行时的输出中是否存在绑定错误?您期望触发什么事件?我敢打赌,我通常不是下注类型,但我会怀疑绑定错误其次我还会怀疑您可能会遇到与视觉树相关的 CM 限制

    【讨论】:

    • 我在输出窗口中没有看到绑定错误;并且,是的,我已经将该 event-code-sn-p 移动到带有和不带参数的 FileSystemViewModel 中。感谢您的回复。
    • 当你说事件时,你期待哪些事件?
    • 任何事件,但 Loaded 都可以正常工作,因为它将是第一个在没有任何鼠标点击等情况下执行的事件。此解决方案可能有效;但是,它非常复杂:stackoverflow.com/questions/25649851/…。使用 MVVMLight 时,我没有任何这些问题。
    • 正确的原因MVVMLight不是CM,CM是ViewModel First,MVVMLight是ViewFirst开发。
    • 所以现在建议不要尝试“使用户控件工作”作为事件控件,而是尝试将其附加到实际的 DirectoryView,如果需要,使用适当的视图模型方法连接加载的事件,看看是否这样可行。唯一的其他选择是做一个 DP
    【解决方案3】:

    使用 Galasoft MVVMlight。没有关于位于其他视图中的事件的此类问题,无论是否包含。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 2019-12-11
      • 2013-12-30
      相关资源
      最近更新 更多