简体   繁体   中英

Binding two XAML element properties to the same ViewModel property does not work

Problem description

I use the Master Details View control. It has two properties Details Header and SelectedItem . I bind both to the Selected property in ViewModel . The goal is to change the DetailsHeader header depending on the selected item. The problem is that only SelectedItem is updated. The text does not appear in the DetailsHeader .

DetailsHeader="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"

If link one to the other, it works correctly - both are updated.

DetailsHeader="{x:Bind masterDetailsView.SelectedItem, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"

I do not find in the documentation a restriction on the fact that a property from a context can only be bound to one property of a XAML element. What could be the problem?

Code

ViewModelBase from MVVM Light is used for notification of changes. Its Set() method updates the property and raises a change event.

private SampleVendorModel _selected;
public SampleVendorModel Selected 
{ 
    get => _selected;
    set => Set(ref _selected, value);
}

Model

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>

Resource's page

<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

I wronged. MasterDetailsView.SelectedItem is updated via property ViewModel.Selected in the code. In case UI navigation, ViewModel.Selected doesn't change. Because binding mode is OneWay . As a consequence, MasterDetailsView.DetailsHeader doesn't get notify about change selected.

In order to solve the problem, need to set mode as TwoWay for MasterDetailsView.SelectedItem .

DetailsHeader="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=TwoWay}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM