2

让我解释一下我的问题。请原谅我的长问题。就这样吧。

我有一个视图(BusyProviderView

<Grid>
    <xctk:BusyIndicator x:Name="aaa" IsBusy="{Binding IsRunning}" >
        <xctk:BusyIndicator.BusyContentTemplate>
            <DataTemplate>
                <Grid cal:Bind.Model="{Binding}">
                    <TextBlock Name="Message"/>
                </Grid>
            </DataTemplate>
        </xctk:BusyIndicator.BusyContentTemplate>
    </xctk:BusyIndicator>
</Grid>

哪个有视图模型:

    public class BusyProviderViewModel : PropertyChangedBase, IBusyProvider
{
//two properties with INPC, Message and IsRunning
}

我再次有一个Shell 视图

<Window x:Class="MvvmTest.ShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ShellView" Height="300" Width="300">
<Grid>
    <Button Height="25" x:Name="Run">Run</Button>
    <ContentControl x:Name="BusyProvider"/>
</Grid>

哪个有视图模型

public class ShellViewModel : PropertyChangedBase, IShellViewModel
{
    private IBusyProvider busyProvider;

    public ShellViewModel(IBusyProvider busy)
    {
        this.BusyProvider = busy;
    }

    public IEnumerable<IResult> Run()
    {
        yield return new DummyOperation(this.BusyProvider);
    }

    public IBusyProvider BusyProvider
    {
        get
        {
            return this.busyProvider;
        }
        set
        {
            if (Equals(value, this.busyProvider))
            {
                return;
            }
            this.busyProvider = value;
            this.NotifyOfPropertyChange(() => this.BusyProvider);
        }
    }
}

DummyOperation外观

public class DummyOperation : IResult
{
    public IBusyProvider Provider { get; set; }

    public DummyOperation(IBusyProvider provider)
    {
        Provider = provider;
    }

    public void Execute(ActionExecutionContext context)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += (a, b) =>
            {
                Provider.IsRunning = true;
                Provider.Message = "Working";
                Thread.Sleep(TimeSpan.FromSeconds(5));
                Provider.Message = "Stopping";
                Thread.Sleep(TimeSpan.FromSeconds(5));
                Provider.IsRunning = false;
            };
        worker.RunWorkerCompleted += (a, b) =>
            { Completed(this, new ResultCompletionEventArgs()); };
        worker.RunWorkerAsync();

    }

    public event EventHandler<ResultCompletionEventArgs> Completed;
}

最后我有BootStrapper

public class AppBootstrapper : Bootstrapper<IShellViewModel>
{
    private Container container;

    protected override void Configure()
    {
        this.container = new Container();
        this.container.Register<IWindowManager,WindowManager>();
        this.container.Register<IShellViewModel,ShellViewModel>();
        this.container.Register<IBusyProvider, BusyProviderViewModel>();
    }

    protected override object GetInstance(Type serviceType, string key)
    {

        return this.container.GetInstance(serviceType);
    }


    protected override IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return this.container.GetAllInstances(serviceType);
    }
    protected override void BuildUp(object instance)
    {
        this.container.Verify();
    }
}

看起来我已经设置了所有内容,但是当我尝试运行它时会引发异常。 在此处输入图像描述

我确定问题是由

 <DataTemplate>
            <Grid cal:Bind.Model="{Binding}">
                <TextBlock Name="Message"/>
            </Grid>
        </DataTemplate>

cal:Bind.Model="{绑定}

一旦我删除了上述语句,程序就会运行而不会崩溃但没有绑定。

如果你看图像,

 protected override object GetInstance(Type serviceType, string key)
    {

        return this.container.GetInstance(serviceType);
    }

serviceType 作为NULL传递,键是“请稍候....”,这是从哪里来的??

4

2 回答 2

5

默认情况下,扩展工具包似乎BusyIndicator使用字符串"Please Wait...."作为BusyContent. 所以里面DataTemplateDataContext是上面提到的字符串,这会导致 Caliburn 中的混乱和异常。

要修复它,您需要将BusyContenton设置BusyIndicator为当前DataContext并且它将起作用:

<xctk:BusyIndicator x:Name="aaa" IsBusy="{Binding IsRunning}" 
                                 BusyContent="{Binding}" >
    <xctk:BusyIndicator.BusyContentTemplate>
        <DataTemplate>
            <Grid cal:Bind.Model="{Binding}">
                <TextBlock Name="Message"/>
            </Grid>
        </DataTemplate>
    </xctk:BusyIndicator.BusyContentTemplate>
</xctk:BusyIndicator>
于 2012-08-18T16:22:56.023 回答
0

我认为 Oleg 是对的,你不能在使用 Caliburn 的 DataTemplate 中使用约定(你可以使用 CaliburnMicro)。从文档 - 其他要知道的事情

其他要知道的事情 在所有平台上,约定不能应用于 DataTemplate 的内容。这是 Xaml 模板系统的当前限制。我已经要求微软解决这个问题,但我怀疑他们会回应。因此,为了将 Binding 和 Action 约定应用于您的 DataTemplate,您必须将 Bind.Model="{Binding}" 附加属性添加到 DataTemplate 内的根元素。这为 Caliburn.Micro 提供了必要的钩子,以便在每次从 DataTemplate 实例化 UI 时应用其约定。

于 2012-08-18T15:04:35.530 回答