ViewModel - 从(子)ItemsControl 中绑定父视图
ViewModel-Binding of parent view from within a (child) ItemsControl
在我们的 C# WPF 应用程序(使用 Caliburn.Micro 框架)中,我们有一个视图和一个视图模型。在 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}">
好的,问题找到了..>.>
我和一个同事尝试了更多的东西,比如:
将此添加到 window:
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... :
Dossiernummer = state.Dossiernummer ?? state.UbizzDossiernummer;
(UbizzDossiernummer 是我们要替换的旧系统的编号(我们已将其导入到我们的应用程序中),Dossiernummer 是我们应用程序中创建的对象的新编号。我一直在测试的对象这是进口的..)
所以,我把它改回了:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Dossiernummer}"/>
而且有效..
在我们的 C# WPF 应用程序(使用 Caliburn.Micro 框架)中,我们有一个视图和一个视图模型。在 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}">
好的,问题找到了..>.>
我和一个同事尝试了更多的东西,比如:
将此添加到 window:
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... :
Dossiernummer = state.Dossiernummer ?? state.UbizzDossiernummer;
(UbizzDossiernummer 是我们要替换的旧系统的编号(我们已将其导入到我们的应用程序中),Dossiernummer 是我们应用程序中创建的对象的新编号。我一直在测试的对象这是进口的..)
所以,我把它改回了:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Dossiernummer}"/>
而且有效..