DataTemplateSelector / Binding不起作用

时间:2012-08-24 06:54:35

标签: c# wpf binding datatemplate datatemplateselector

这是我的ViewModel:

class MainViewModel : ViewModelBase
{
    private CalculatorViewModel calc;
    public CalculatorViewModel Calculator {get {return calc; }set {calc = value; RaisePropertyChanged("Calculator");}}
}

class CalculatorViewModel : ViewModelBase
{
    private CalculatorMode mode;
    public CalculatorMode Mode {get {return mode;}set{mode=value; RaisePropertyChanged("CalculatorMode");}}

    public CalculatorViewModel()
    {
        Mode = new HexMode();
    }
}
abstract class CalculatorMode : ViewModelBase
{
    abstract int Calculate(...);
}
class HexMode : CalculatorMode
{
public int Calculate(...) { ...}
}

这是我的MainWindow(MainViewModel实例设置为Windows的DataContext):

<ad:DockingManager >
            <ad:DockingManager.LayoutItemTemplateSelector>
                <vm:PanesTemplateSelector>
                    <vm:PanesTemplateSelector.FileViewTemplate>
                        <DataTemplate>
                            <h:MyDocument  />
                        </DataTemplate>
                    </vm:PanesTemplateSelector.FileViewTemplate>
                    <vm:PanesTemplateSelector.CalculatorViewTemplate>
                        <DataTemplate>
                            <w:Calculator  />
                        </DataTemplate>
                    </vm:PanesTemplateSelector.CalculatorViewTemplate>
                </vm:PanesTemplateSelector>
            </ad:DockingManager.LayoutItemTemplateSelector>
</ad:DockingManager>

PanesTemplateSelector-Class代码:

public DataTemplate FileViewTemplate
        {
            get;
            set;
        }

        public DataTemplate CalculatorViewTemplate
        {
            get;
            set;
        }

        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            if (item is DocumentViewModel)
                return FileViewTemplate;

            if (item is CalcualtorViewModel)
                return CalculatorViewTemplate;

            return base.SelectTemplate(item, container);
        }

计算器控制的内容:

<Grid Name="main">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ContentControl Name="content">
        <ContentControl.ContentTemplateSelector>
            <vm:CalculatorTemplateSelector>
                <vm:CalculatorTemplateSelector.DefaultView>
                    <DataTemplate>
                        <TextBlock Text="Dummy for normal view" Foreground="Wheat" />
                    </DataTemplate>
                </vm:CalculatorTemplateSelector.DefaultView>
                <vm:CalculatorTemplateSelector.HexView>
                    <DataTemplate>
                        <TextBlock Text="Dummy für Hexview" Foreground="Gray"/>
                    </DataTemplate>
                </vm:CalculatorTemplateSelector.HexView>
            </vm:CalculatorTemplateSelector>
        </ContentControl.ContentTemplateSelector>
    </ContentControl>
</Grid>

CalculatorTemplateSelector-Class的代码:

public DataTemplate HexView
        {
            get;
            set;
        }

        public DataTemplate DefaultView
        {
            get;
            set;
        }

        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            CalculatorViewModel cjmv = (CalculatorViewModel)item;

            if (cjmv != null)
            {
                if (cjmv.Mode is HexMode)
                    return HexView;

        return DefaultView;
            }

            return base.SelectTemplate(item, container);
        }

第一个TemplateSelector工作正常。选择了正确的模板,我可以看到计算器控制。但是Calculator-Control中的TemplateSelector不起作用。在CalculatorTemplateSelector.SelectTemplate中,item-parameter始终为null。但我需要那里有CalculatorViewModel实例。我想我的问题是一个有约束力的问题,但我没有找到解决方案。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

但有一件事是肯定的:

public CalculatorMode Mode [...] RaisePropertyChanged("CalculatorMode");}}

应该是:RaisePropertyChanged("Mode");}}

答案 1 :(得分:0)

我可能会问,但只是为了让你了解我的才华......我自己找到了一个解决方案: 将DataContext-Binding添加到ContentPresenter(而不是ContentControl)

<ContentPresenter Name="content" DataContext="{Binding}">

并将SelectTemplate-Implementation更改为:

 public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            ContentPresenter cp = container as ContentPresenter;
            if (cp != null)
            {
                CalculatorViewModel model = cp.DataContext as CalculatorViewModel;
                if (model != null)
                {
                    if (model.Mode is DefaultMode)
                        return DefaultView;
                    if (model.Mode is HexMode)
                        return HexView;
                }
            }
            return base.SelectTemplate(item, container);
        }

无论如何,感谢错误的RaisePropertyChanged-Call

的通知