数据绑定无法在Avalondock窗口

时间:2015-06-13 11:04:36

标签: c# wpf data-binding avalondock

我有一个使用AvalonDock的Window Manager项目。

基本上有两个元素:一个LayoutAnchorableItem显示我的不同工具框(当前一个,包含一个Treeview)和一个LayoutItem来显示用树视图打开的文档(一个自定义控件,具有可绑定参数 - 理论上)

DockingManager的ViewModel托管将成为LayoutItems的ObservableCollection Panes

事情有效"罚款"如果我不尝试绑定XAML中的参数,并强制像这样的值

<avalonDock:DockingManager.LayoutItemTemplateSelector>
    <panes:PanesTemplateSelector>
        <panes:PanesTemplateSelector.ExchangeViewTemplate>
            <DataTemplate>
                <xchng:Exchange/>
            </DataTemplate>
        </panes:PanesTemplateSelector.ExchangeViewTemplate>
        <panes:PanesTemplateSelector.GraphViewTemplate>
            <DataTemplate>
                <grph:Graph TickerCode="ILD" ExchangeCode="EPA"/>
            </DataTemplate>
        </panes:PanesTemplateSelector.GraphViewTemplate>
    </panes:PanesTemplateSelector>
</avalonDock:DockingManager.LayoutItemTemplateSelector>

Exchange是工具箱,Graph是LayoutItems。

停靠管理器的初始数据绑定如下所示:

<avalonDock:DockingManager Margin="0,0,0,0" 
                         Grid.Row="1"
                         AnchorablesSource="{Binding Tools}"
                         DocumentsSource="{Binding Panes}" 
                         ActiveContent="{Binding ActiveDocument, Mode=TwoWay, Converter={StaticResource ActiveDocumentConverter}}"
                         x:Name="dockManager">

请注意,窗格的类型为GraphViewModel,其中包含两个公开参数:ExchangeCodeTickerCode

问题是我想将TickerCodeExchangeCode绑定到Panes.TickerCode和Panes.ExchangeCode值。

所以我尝试了这个:

<grph:Graph TickerCode="{Binding TickerCode, UpdateSourceTrigger=PropertyChanged}" ExchangeCode="{Binding ExchangeCode, UpdateSourceTrigger=PropertyChanged}"/>

但它什么都不做:自定义控件中的TickerCode和ExchangeCode等于"",这与强制XAML中的值相反。

另外有点奇怪的是,如果我介入代码执行,Panes实际上有TickerCode和ExchangeCode的值,它们就不会绑定。例如,实际创建窗格的代码是

public void AddGraph(string FullName, string ExchangeCode, string TickerCode)
    {
        var graphViewModel = new GraphViewModel(FullName, ExchangeCode, TickerCode);
        _panes.Add(graphViewModel);
        ActiveDocument = graphViewModel;

    }

这里,每一步都有两个值。让我们想象一下,我添加了5个不同的窗格,它们都带有正确的ExchangeCode和TickerCode,但没有任何内容传递给自定义控件。

如果您需要有关我的自定义控件的更多信息,请输入以下代码:Passing parameters to custom control (databinding)

备注:如您所见,我没有放置大部分代码,如果您认为它可能会有所帮助,请提出请求,我会添加所需的内容。请注意,整个窗口管理器的全局逻辑与AvalonDock测试应用程序(AvalonDock.MVVMTestApp)中提供的相同。

1 个答案:

答案 0 :(得分:0)

例如,如果我有ChartView和ChartViewModel: 在MainWindow.xaml中:

    <xcad:DockingManager x:Name="dockingManager"
                         AnchorablesSource="{Binding Path=Anchorables}"
                         DocumentsSource="{Binding Path=Documents}"
                         ActiveContent="{Binding Path=ActiveDocument, Mode=TwoWay, Converter={StaticResource ActiveDocumentConverter}}">

        <xcad:DockingManager.LayoutItemTemplateSelector>
            <selfViewPane:PaneTemplateSelector>
                <selfViewPane:PaneTemplateSelector.ChartViewTemplate>
                    <DataTemplate>
                        <selfViewDocument:ChartView />
                    </DataTemplate>
                </selfViewPane:PaneTemplateSelector.ChartViewTemplate>
            </selfViewPane:PaneTemplateSelector>
        </xcad:DockingManager.LayoutItemTemplateSelector>

        <xcad:DockingManager.LayoutItemContainerStyleSelector>
            <selfViewPane:PaneStyleSelector>
                <selfViewPane:PaneStyleSelector.ChartViewStyle>
                    <Style TargetType="{x:Type xcad:LayoutItem}">
                        <Setter Property="Title" Value="{Binding Model.Title}"/>                                
                        <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}"/>
                        <Setter Property="IconSource" Value="{Binding Model.IconSource}"/>
                        <Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
                    </Style>
                </selfViewPane:PaneStyleSelector.ChartViewStyle>
            </selfViewPane:PaneStyleSelector>
        </xcad:DockingManager.LayoutItemContainerStyleSelector>

        <xcad:DockingManager.LayoutUpdateStrategy>
            <selfViewPane:LayoutInitializer />
        </xcad:DockingManager.LayoutUpdateStrategy>

        <xcad:LayoutRoot>
            <xcad:LayoutPanel Orientation="Horizontal">
                <xcad:LayoutAnchorablePane Name="ToolsPane" DockWidth="200">
                </xcad:LayoutAnchorablePane>
                <xcad:LayoutDocumentPane />
            </xcad:LayoutPanel>
        </xcad:LayoutRoot>                
    </xcad:DockingManager>

和: 在ChartViewModel中,我有属性ChartPlotModel:

/// <summary>
/// Gets or sets the ChartPlotModel.
/// </summary>
public PlotModel ChartPlotModel
{
    get
    {
        return this.chartPlotModel;
    }

    set
    {
        if (this.chartPlotModel != value)
        {
            this.chartPlotModel = value;
            this.RaisePropertyChanged("ChartPlotModel");
        }
    }
}

在ChartView中我可以绑定:

<UserControl x:Class="Jofta.Analyzer.UI.Classes.View.Document.ChartView"
             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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
             xmlns:oxy="http://oxyplot.org/wpf"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <xctk:BusyIndicator IsBusy="{Binding Path=IsBusy}">
        <Grid>
            <oxy:PlotView Model="{Binding ChartPlotModel}" />
        </Grid>
    </xctk:BusyIndicator>

</UserControl>

在这个例子中,我从oxyplot绑定到PlotView,但我认为,你可以使用这种模式。你有GraphViewModel,GraphView和TickerCode以及ExchangeCode。