Caliburn绑定异常

时间:2012-08-18 14:45:01

标签: c# wpftoolkit caliburn.micro simple-injector

让我解释一下我的问题。请原谅我这个长期的问题。 在这里。

我有一个视图( 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();
    }
}

看起来我已经设定了一切, 但是当我尝试运行它时抛出一个异常。 enter image description here

我确定问题是由

引起的
 <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 传递,密钥为“Please Wait ....”, 那来自哪里?

2 个答案:

答案 0 :(得分:5)

默认情况下,Extended ToolkitBusyIndicator似乎使用"Please Wait...."字符串BusyContent。所以在DataTemplate DataContext内部将是上面提到的字符串,这会导致Caliburn中的混淆和异常。

要解决此问题,您需要将BusyContent上的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>

答案 1 :(得分:0)

我认为Oleg是正确的,你不能在使用Caliburn的DataTemplate中使用约定(你可以使用CaliburnMicro)。来自Documentation - Other Things to Know

  

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