英文:
Why is my Child View not displayed when I show my Container View in the MainWindow with WPF ReactiveUI?
问题
在主窗口中显示ContainerView
时,ChildView
未显示的原因可能是模板(ControlTemplate
)中的问题。你的模板设置如下:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="views:ContainerView">
<Grid>
<reactiveUi:ViewModelViewHost x:Name="Child"></reactiveUi:ViewModelViewHost>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
在这个模板中,你使用了ViewModelViewHost
来托管Child
视图模型,但你没有在ViewModelViewHost
中定义具体的视图。要显示ChildView
,你需要在这个模板中添加ChildView
控件。可以尝试将ChildView
添加到ViewModelViewHost
中,如下所示:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="views:ContainerView">
<Grid>
<reactiveUi:ViewModelViewHost x:Name="Child">
<views:ChildView />
</reactiveUi:ViewModelViewHost>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
这将在ViewModelViewHost
中显示ChildView
,并且ChildView
的样式应该正常工作。希望这可以解决问题。
英文:
I am currently learning my way around WPF and ReactiveUI. I try to explain my problem with a simplified example. I have a ContainerView that contains a ChildView and is bound to a ContainerViewModel. The ContainerViewModel has a property Child that is bound to the ChildView control. The ChildView control has a corresponding ChildViewModel.
I also have a style for my ContainerView that sets the Template property to a ControlTemplate with a Grid that contains a ViewModelViewHost control named "Child".
However, when I show the ContainerView in the MainWindow, the ChildView is not displayed.
Here's the code for the ContainerView/ViewModel and its style:
public class ContainerView : Control, IViewFor<ContainerViewModel>
{
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(
nameof(ViewModel), typeof(ContainerViewModel), typeof(ContainerView), new PropertyMetadata(default(ContainerViewModel)));
public ContainerViewModel ViewModel
{
get { return (ContainerViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (ContainerViewModel)value;
}
public ContainerView()
{
this.WhenActivated(d =>
{
this.OneWayBind(ViewModel, vm => vm.Child, view => view.Child.ViewModel);
});
}
private ViewModelViewHost Child { get; set; }
public override void OnApplyTemplate()
{
Child = GetTemplateChild(nameof(Child)) as ViewModelViewHost;
}
}
public class ContainerViewModel : ReactiveObject
{
private ChildViewModel _child;
public ChildViewModel Child
{
get => _child;
set => this.RaiseAndSetIfChanged(ref _child, value);
}
public ContainerViewModel()
{
Child = new ChildViewModel();
}
}
<Style TargetType="{x:Type views:ContainerView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="views:ContainerView">
<Grid>
<reactiveUi:ViewModelViewHost x:Name="Child"></reactiveUi:ViewModelViewHost>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here's the code for the "ChildView" and its style:
public class ChildView : Control, IViewFor<ChildViewModel>
{
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(
nameof(ViewModel), typeof(ChildViewModel), typeof(ChildView), new PropertyMetadata(default(ChildViewModel)));
public ChildViewModel ViewModel
{
get { return (ChildViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (ChildViewModel)value;
}
public ChildView()
{
DefaultStyleKey = nameof(ChildView);
}
}
<Style TargetType="{x:Type views:ChildView}">
<Setter Property="Background" Value="Brown"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="views:ChildView">
<Ellipse Width="200" Height="200" Fill="Yellow" ></Ellipse>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any idea why the ChildView is not displayed?
答案1
得分: 0
Ok, 我明白了.. 我不确定这是否是最佳解决方案,但对我来说有效。我必须自己在 View 中实例化 ViewModel。
public ContainerView()
{
this.ViewModel = new ContainerViewModel();
this.WhenActivated(d =>
{
this.OneWayBind(ViewModel, vm => vm.Child, view => view.Child.ViewModel);
});
}
英文:
Ok, I think i got it.. I don't no if this is the best solution, but it works for me. I had to instantiate the ViewModel in the View by myself.
public ContainerView()
{
this.ViewModel = new ContainerViewModel();
this.WhenActivated(d =>
{
this.OneWayBind(ViewModel, vm => vm.Child, view => view.Child.ViewModel);
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论