AvalonDoc:无法按行为扩展LayoutAnchorable(MVVM)

时间:2016-09-14 09:52:08

标签: c# wpf mvvm avalondock

我正在使用文档选项卡和面板(如在Visual Studio中)使用AvalonDock 2 + Caliburn.Micro + Fody.PropertyChanged处理MDI应用程序。我想从代码中扩展LayoutAnchorable(当你在项目中开始搜索时,这样可以在Visual Studio中工作:面板,屏幕底部的搜索结果会自动展开)。

根据MVVM方法我做了行为,绑定了LAyoutAnchorable的IsActive属性 - 并且它不起作用。更准确地说,它仅在一个方向上起作用:我在ViewModel中收到通知(当用户点击打开面板时),但我无法从代码中打开面板。这是代码。谢谢。

查看:

<xcad:LayoutRoot.BottomSide>
    <xcad:LayoutAnchorSide>
        <xcad:LayoutAnchorGroup>
                <xcad:LayoutAnchorable x:Name="ErrorsListPanel" Title="Errors List" AutoHideHeight="300">

                    <i:Interaction.Behaviors>
                        <behaviors:LayoutAnchorableBehaviour IsLayoutActive="{Binding IsErrorsListActive,
                                                            Mode=OneWay,
                                                            UpdateSourceTrigger=PropertyChanged}"/>

                    </i:Interaction.Behaviors>


                    <ListView caliburn:Message.Attach="[Event SelectionChanged] = [Action BrowseError($this)]" ItemsSource="{Binding ErrorsList}">

                        <ListView.Resources>
                            <Style TargetType="{x:Type GridViewColumnHeader}">
                                <Setter Property="HorizontalContentAlignment" Value="Left" />
                            </Style>
                        </ListView.Resources>

                        <ListView.View>
                            <GridView>

                                <GridViewColumn Width="500"
                                            DisplayMemberBinding="{Binding Path=File.RelPath}"
                                            Header="File" />

                                <GridViewColumn Width="500"
                                            DisplayMemberBinding="{Binding Path=Message}"
                                            Header="Description" />
                                <GridViewColumn Width="50"
                                            DisplayMemberBinding="{Binding Path=Line}"
                                            Header="Line" />
                                <GridViewColumn Width="50"
                                            DisplayMemberBinding="{Binding Path=Column}"
                                            Header="Column" />
                            </GridView>
                        </ListView.View>
                    </ListView>

                </xcad:LayoutAnchorable>
...
....

行为:

public sealed class LayoutAnchorableBehaviour : Behavior<LayoutAnchorable>
{
    public static readonly DependencyProperty IsLayoutActiveProperty =
        DependencyProperty.Register("IsLayoutActive", typeof(bool), typeof(LayoutAnchorableBehaviour),
        new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            (dependencyObject, dependencyPropertyChangedEventArgs) =>
            {
                var behavior = dependencyObject as LayoutAnchorableBehaviour;
                var layout = behavior?.AssociatedObject as LayoutAnchorable;
                if (layout == null) return;
                layout.IsActive = (bool) dependencyPropertyChangedEventArgs.NewValue;

            }));

    public bool IsLayoutActive
    {
        get { return (bool)GetValue(IsLayoutActiveProperty); }
        set { SetValue(IsLayoutActiveProperty, value); }
    }


    protected override void OnAttached()
    {
        base.OnAttached();
        if (AssociatedObject != null)
        {
            AssociatedObject.IsActiveChanged += AssociatedObject_IsActiveChanged;
        }
    }

    private void AssociatedObject_IsActiveChanged(object sender, EventArgs e)
    {
        var layout = sender as LayoutAnchorable;
        if (layout != null)
        {
            IsLayoutActive = layout.IsActive;
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        if (AssociatedObject != null)
        {
            AssociatedObject.IsActiveChanged -= AssociatedObject_IsActiveChanged;
        }
    }
}

视图模型:

[ImplementPropertyChanged]
public class ProjectViewModel : Screen
{
    public bool IsErrorsListActive { get; set; }
    ...
    public void BrowseErrorsCommand()
    {
        IsErrorsListActive = true;
    }
}

UPD1:依赖项属性中的lambda函数IsLayoutActiveProperty在ViewModel中未被IsErrorsListActive = true调用。也许这会有所帮助。

0 个答案:

没有答案