Caliburn.Micro Binding 似乎无法在视图模型中解析

发布于 2024-12-28 05:24:26 字数 2564 浏览 3 评论 0原文

我有一个名为 Report 的数据传输对象。这些报表对象保存在名为 Controller 的不同类中的可观察集合中。我想要做的是创建一个视图,从Report 中获取数据并将其显示在列表中。

我遇到的问题是我似乎无法将视图正确绑定到视图模型。我设法通过使用值转换器并返回我需要的视图模型来绑定它,但即使附加了视图,绑定似乎也无法解析。

包含 Report 列表的视图模型:

public class ReportListViewModel : Screen, IModule
{
    private Controller _controller;
    public Controller Controller
    {
        get { return _controller; }
        set { _controller = value; }
    }

    public ReportListViewModel(Controller controller)
    {
        Controller = controller;
        Controller.Domain.Reports.Add(new Model.Report() { Notes = "Test Data.." });
    }
}

及其 XAML 视图:

<Grid Background="Blue">
    <StackPanel>
        <StackPanel.Resources>
            <local:ReportToListItem x:Key="reportToListItem" />
        </StackPanel.Resources>
        <ListBox Height="100" x:Name="Controller_Domain_Reports">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ContentControl Content="{Binding Converter={StaticResource reportToListItem}}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</Grid>

值转换器:

internal class ReportToListItem : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var vm = IoC.Get<ReportListItemViewModel>();
        vm.Report = (Report)value;
        var view = ViewLocator.GetOrCreateViewType(typeof(ReportListItemView));
        ViewModelBinder.Bind(vm, view, null);
        return view;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

以下是负责显示 Report< 数据的视图模型和视图/代码> 对象。

Viewmodel:

public class ReportListItemViewModel : Screen
{
    private Report _report;
    public Report Report
    {
        get { return _report; }
        set { _report = value; }
    }
}

View:

<Grid>
    <TextBlock Text="{Binding Report, Path=Notes}" />
</Grid>

现在我知道视图正在附加,因为 ReportListItemViewModelOnViewAttached 方法被触发。我知道视图也被初始化,因为它的构造函数被触发。

ReportListItemViewModel.Report 上的 getter 永远不会被调用。

那么 Binding 出了什么问题呢?

I have an data transfer object called Report. These report objects are held in an observable collection in a different class called Controller. What I am trying to do is create a view that takes data from the Report and displays that in a list.

The problem I am having is that I cannot seem to bind the view properly to the view model. I managed to get it to bind by using a value converter and returning the viewmodel that I need but the Bindings do not seem to resolve even though the view is attached.

The viewmodel that contains the Report list:

public class ReportListViewModel : Screen, IModule
{
    private Controller _controller;
    public Controller Controller
    {
        get { return _controller; }
        set { _controller = value; }
    }

    public ReportListViewModel(Controller controller)
    {
        Controller = controller;
        Controller.Domain.Reports.Add(new Model.Report() { Notes = "Test Data.." });
    }
}

And the XAML view for it:

<Grid Background="Blue">
    <StackPanel>
        <StackPanel.Resources>
            <local:ReportToListItem x:Key="reportToListItem" />
        </StackPanel.Resources>
        <ListBox Height="100" x:Name="Controller_Domain_Reports">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ContentControl Content="{Binding Converter={StaticResource reportToListItem}}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</Grid>

The value converter:

internal class ReportToListItem : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var vm = IoC.Get<ReportListItemViewModel>();
        vm.Report = (Report)value;
        var view = ViewLocator.GetOrCreateViewType(typeof(ReportListItemView));
        ViewModelBinder.Bind(vm, view, null);
        return view;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And here are the viewmodel and view that are going to be responsible for displaying the data of the Report object.

Viewmodel:

public class ReportListItemViewModel : Screen
{
    private Report _report;
    public Report Report
    {
        get { return _report; }
        set { _report = value; }
    }
}

View:

<Grid>
    <TextBlock Text="{Binding Report, Path=Notes}" />
</Grid>

Now I know that the view is being attached because the OnViewAttached method of the ReportListItemViewModel is triggered. I know the view is being initialed too because it's constructor is triggered.

But the getter on the ReportListItemViewModel.Report is never called.

So what is going wrong with the Binding?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷默言语 2025-01-04 05:24:26

要使用 caliburn 自动加载视图,您必须绑定到 Caliburn 的附加属性:

<ContentControl cal:View.Model="{Binding ...}"/>

否则您不会将相应的视图加载到内容控件中,而是加载视图模型本身。

编辑:

上面的东西似乎是无意义的,因为OP说视图被创建,我也认为我发现了实际的问题:

如果你像这样设置绑定:

<TextBlock Text="{Binding Report, Path=Notes}" />

它不会工作,因为你正在覆盖路径报告注释。要访问 Report 中的 Notes 属性,您必须像这样指定项目:

<TextBlock Text="{Binding Report.Notes}" />

或像这样:

<TextBlock Text="{Binding Path=Report.Notes}" />

To load the view automatically with caliburn, you have to bind to Caliburn's attached properties:

<ContentControl cal:View.Model="{Binding ...}"/>

Otherwise you won't load the corresponding view into the content control but the viewmodel itself.

Edit:

The stuff above seems to be nonsense, since the OP says the view gets created, also I think I spotted the actual problem:

If you set the binding like this:

<TextBlock Text="{Binding Report, Path=Notes}" />

it won't work, since you are overwriting the path Report with Notes. To access the Notes property in Report, you have to specify the item like this:

<TextBlock Text="{Binding Report.Notes}" />

or like this:

<TextBlock Text="{Binding Path=Report.Notes}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文