将两个 XAML 元素属性绑定到同一个 ViewModel 属性 不起作用
Binding two XAML element properties to the same ViewModel property does not work
问题描述
我用的是Master Details View控件。它有两个属性 Details Header
和 SelectedItem
。我将两者都绑定到 ViewModel
中的 Selected
属性。目标是根据所选项目更改 DetailsHeader
header。问题是只有 SelectedItem
被更新了。文本未出现在 DetailsHeader
.
中
DetailsHeader="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
如果 link 一个到另一个,它工作正常 - 两者都已更新。
DetailsHeader="{x:Bind masterDetailsView.SelectedItem, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
我在文档中没有发现对上下文中的 属性 只能绑定到 XAML 元素的一个 属性 这一事实的限制。可能是什么问题?
代码
来自 MVVM Light
的 ViewModelBase
用于更改通知。它的 Set()
方法更新 属性 并引发更改事件。
private SampleVendorModel _selected;
public SampleVendorModel Selected
{
get => _selected;
set => Set(ref _selected, value);
}
型号
public class SampleVendorModel
{
public string Name { get; set; }
public string Surname { get; set; }
public string MiddleName { get; set; }
public string FullName => $"{Surname} {Name} {MiddleName}";
public string NameWithoutSurname => $"{Name} {MiddleName}";
}
MasterDetailsView
<controls:MasterDetailsView Name="masterDetailsView"
MasterHeader="{x:Bind ViewModel.Title}"
MasterHeaderTemplate="{StaticResource MasterHeaderTemplate}"
DetailsHeader="{x:Bind masterDetailsView.SelectedItem, Mode=OneWay}"
DetailsHeaderTemplate="{StaticResource DetailsHeaderTemplate}"
ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
ItemTemplate="{StaticResource ItemTemplate}"
DetailsTemplate="{StaticResource DetailsTemplate}"
BorderBrush="Transparent"
BackButtonBehavior="Manual">
</controls:MasterDetailsView>
资源页面
<Page.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="30" />
<Setter Property="FontWeight" Value="Light" />
<Setter Property="Margin" Value="0, 10, 0, 10" />
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
</Style>
<DataTemplate x:Key="MasterHeaderTemplate">
<TextBlock Text="{Binding}" Style="{StaticResource HeaderStyle}"/>
</DataTemplate>
<DataTemplate x:Key="DetailsHeaderTemplate" x:DataType="viewmodels:SampleVendorModel">
<TextBlock Text="{x:Bind FullName}" Style="{StaticResource HeaderStyle}" />
</DataTemplate>
<DataTemplate x:Key="ItemTemplate" x:DataType="viewmodels:SampleVendorModel">
<Grid Margin="0, 10, 0, 10" RowSpacing="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{x:Bind Surname}" FontWeight="Bold" FontSize="16" TextTrimming="CharacterEllipsis" />
<TextBlock Grid.Row="1" Text="{x:Bind NameWithoutSurname}" TextTrimming="CharacterEllipsis" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="DetailsTemplate"
x:DataType="viewmodels:SampleVendorModel">
<StackPanel Margin="10">
<TextBlock Text="{x:Bind Surname}" />
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind MiddleName}" />
</StackPanel>
</DataTemplate>
</Page.Resources>
The problem is that only SelectedItem is updated
我委屈了。 MasterDetailsView.SelectedItem
通过代码中的 属性 ViewModel.Selected
更新。如果 UI 导航,ViewModel.Selected
不会改变。因为绑定模式是OneWay
。因此,MasterDetailsView.DetailsHeader
不会收到有关所选更改的通知。
为了解决问题,需要将MasterDetailsView.SelectedItem
的模式设置为TwoWay
。
DetailsHeader="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=TwoWay}"
问题描述
我用的是Master Details View控件。它有两个属性 Details Header
和 SelectedItem
。我将两者都绑定到 ViewModel
中的 Selected
属性。目标是根据所选项目更改 DetailsHeader
header。问题是只有 SelectedItem
被更新了。文本未出现在 DetailsHeader
.
DetailsHeader="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
如果 link 一个到另一个,它工作正常 - 两者都已更新。
DetailsHeader="{x:Bind masterDetailsView.SelectedItem, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
我在文档中没有发现对上下文中的 属性 只能绑定到 XAML 元素的一个 属性 这一事实的限制。可能是什么问题?
代码
来自MVVM Light
的 ViewModelBase
用于更改通知。它的 Set()
方法更新 属性 并引发更改事件。
private SampleVendorModel _selected;
public SampleVendorModel Selected
{
get => _selected;
set => Set(ref _selected, value);
}
型号
public class SampleVendorModel
{
public string Name { get; set; }
public string Surname { get; set; }
public string MiddleName { get; set; }
public string FullName => $"{Surname} {Name} {MiddleName}";
public string NameWithoutSurname => $"{Name} {MiddleName}";
}
MasterDetailsView
<controls:MasterDetailsView Name="masterDetailsView"
MasterHeader="{x:Bind ViewModel.Title}"
MasterHeaderTemplate="{StaticResource MasterHeaderTemplate}"
DetailsHeader="{x:Bind masterDetailsView.SelectedItem, Mode=OneWay}"
DetailsHeaderTemplate="{StaticResource DetailsHeaderTemplate}"
ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
ItemTemplate="{StaticResource ItemTemplate}"
DetailsTemplate="{StaticResource DetailsTemplate}"
BorderBrush="Transparent"
BackButtonBehavior="Manual">
</controls:MasterDetailsView>
资源页面
<Page.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="30" />
<Setter Property="FontWeight" Value="Light" />
<Setter Property="Margin" Value="0, 10, 0, 10" />
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
</Style>
<DataTemplate x:Key="MasterHeaderTemplate">
<TextBlock Text="{Binding}" Style="{StaticResource HeaderStyle}"/>
</DataTemplate>
<DataTemplate x:Key="DetailsHeaderTemplate" x:DataType="viewmodels:SampleVendorModel">
<TextBlock Text="{x:Bind FullName}" Style="{StaticResource HeaderStyle}" />
</DataTemplate>
<DataTemplate x:Key="ItemTemplate" x:DataType="viewmodels:SampleVendorModel">
<Grid Margin="0, 10, 0, 10" RowSpacing="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{x:Bind Surname}" FontWeight="Bold" FontSize="16" TextTrimming="CharacterEllipsis" />
<TextBlock Grid.Row="1" Text="{x:Bind NameWithoutSurname}" TextTrimming="CharacterEllipsis" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="DetailsTemplate"
x:DataType="viewmodels:SampleVendorModel">
<StackPanel Margin="10">
<TextBlock Text="{x:Bind Surname}" />
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind MiddleName}" />
</StackPanel>
</DataTemplate>
</Page.Resources>
The problem is that only SelectedItem is updated
我委屈了。 MasterDetailsView.SelectedItem
通过代码中的 属性 ViewModel.Selected
更新。如果 UI 导航,ViewModel.Selected
不会改变。因为绑定模式是OneWay
。因此,MasterDetailsView.DetailsHeader
不会收到有关所选更改的通知。
为了解决问题,需要将MasterDetailsView.SelectedItem
的模式设置为TwoWay
。
DetailsHeader="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=TwoWay}"