让我解释一下我的问题。请原谅我这个长期的问题。 在这里。
我有一个视图( 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 传递,密钥为“Please Wait ....”, 那来自哪里?
答案 0 :(得分:5)
默认情况下,Extended Toolkit的BusyIndicator
似乎使用"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时应用它的约定。