ViewModel-从(子)ItemsControl中绑定父视图

时间:2015-09-24 06:41:24

标签: c# wpf parent-child viewmodel itemscontrol

在我们的C#WPF应用程序(使用Caliburn.Micro框架)中,我们有一个View和一个ViewModel。在ViewModel中我们有一个字符串属性,我想在ItemsControl的每个子节点内显示这个字符串(这些项目有自己的ViewModel)。我知道我可以将属性传递给每个项目,但不应该这样做。

所以,这是ViewModel的相关部分:

using System;
...

namespace NatWa.MidOffice.Modules.Financien.Views
{
    public class BankgarantieFinancienOpsplitsenViewModel : ValidationBase<BankgarantieFinancienOpsplitsenViewModel>
    {
        ...

        public BankgarantieFinancienOpsplitsenViewModel(BankgarantieFinancienState state, ...)
        {
            ...

            Dossiernummer = state.Dossiernummer;
            Kopers = state.Kopers.Select(k =>
                {
                    var bfkvm = new BankgarantieFinancienKoperViewModel(k, adresService);
                    bfkvm.ObservePropertyChanged(koper => koper.Bedrag).Subscribe(p => CalculateOpenstaandBedrag());
                    return bfkvm;
                }).ToList();

            ...
        }

        public string Dossiernummer
        {
            get { return _dossiernummer; }
            private set
            {
                if (value == _dossiernummer) return;
                _dossiernummer = value;
                NotifyOfPropertyChange(() => Dossiernummer);
            }
        }

        ...
    }
}

观点的相关部分:

<Window x:Class="NatWa.MidOffice.Modules.Financien.Views.BankgarantieFinancienOpsplitsenView"
        ...>

    <Grid Style="{StaticResource WindowPaddingStyle}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            ...
        </Grid.RowDefinitions>

        ...

        <ItemsControl x:Name="Kopers" Grid.Row="1">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="{StaticResource BorderBrush}" BorderThickness="1" Margin="0,3" Padding="5">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>

                            ...

                            <StackPanel Grid.Column="1" Orientation="Vertical">
                                ...

                                <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0,3" HorizontalAlignment="Right">
                                    ...
                                    <!-- THIS IS WHERE I WANT TO DISPLAY THE DOSSIERNUMMER-PROPERTY OF THE PARENT VIEWMODEL -->
                                    <TextBlock Text="{Binding ??Parent??.Dossiernummer}"/>
                                    ...
                                </StackPanel>

                                ...
                            </StackPanel>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        ...
    </Grid>

</Window>

我确实尝试使用以下this SO-answer替换TextBox,但现在结果:

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Dossiernummer}"/>

我还尝试将DataContext绑定添加到Window(即使Caliburn.Micro应该自动执行此操作):

<Window x:Class="NatWa.MidOffice.Modules.Financien.Views.BankgarantieFinancienOpsplitsenView"
        ...
        DataContext="{Binding}">

1 个答案:

答案 0 :(得分:1)

好的,发现问题..&gt;。&gt;

我和一位同事尝试了几件事,比如:

将此添加到窗口:

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignData BankgarantieFinancienOpsplitsenViewModel}" mc:Ignorable="d"

将TextBlock绑定更改为:

<TextBlock Text="{Binding ElementName=Kopers, Path=DataContext.Dossiernummer}"/>

以及其他一些事情,都无济于事。在其他几个观点中,我们已经成功地使用了完全相同的东西,所以我们不知道出了什么问题。然后它打动了我们......

那么,问题是什么?对于我正在测试它的ViewModel,属性中的字符串为null ....当天的好开始犯了这样一个愚蠢的错误..所以,我们已经将ViewModel中的值设置为:< / p>

Dossiernummer = state.Dossiernummer ?? state.UbizzDossiernummer;

(UbizzDossiernummer是我们正在替换的旧系统的编号(我们已将其导入到我们的应用程序中),而Dossiernummer是我们应用程序中制作的对象的新编号。我的目标是一直在测试这是一个导入的..)

所以,我已将其改回:

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Dossiernummer}"/>

它有效..