WPF MainWindow toggle property in UserControl via

2019-08-28 05:59发布

问题:

I have a UserControl within a frame on it's parent window. In the usercontrol, I have a textbox that needs to be edited when a button on the parent window is toggled.

UserControl.xaml

<UserControl.Resources>
    <ResourceDictionary>
        <Style x:Key="TextBoxEdit" TargetType="TextBox">
            <Setter Property="IsReadOnly" Value="True" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding CanEdit}" Value="True">
                    <Setter Property="IsReadOnly" Value="False" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>

</UserControl.Resources>
<Grid>
    <TextBox
        x:Name="EditTextBox"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        Style="{StaticResource TextBoxEdit}"
        Text="Edit me" />
</Grid>

MainWindow.xaml

<Controls:MetroWindow.DataContext>
    <local:ViewModel/>
</Controls:MetroWindow.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <ToggleButton x:Name="EditButton" HorizontalAlignment="Center" VerticalAlignment="Top" IsChecked="{Binding CanEdit}">Edit</ToggleButton>
    <Frame Grid.Row="1" Source="Home.xaml" />
</Grid>

ViewModel

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool canEdit;
    public bool CanEdit
    {
        get { return canEdit; }
        set
        {
            canEdit = value;
            OnPropertyChanged("CanEdit");
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

How do I get the data trigger to work properly? Is the best way to create another view model for the usercontrol and then communicate the values between the 2 viewmodels? If so, how would I do that?

回答1:

Is the best way to create another view model for the usercontrol and then communicate the values between the 2 viewmodels?

The most common way would be for the UserControl to simply inherit the DataContext of the parent window so they both can bind to the same property.

This doesn't work out-of-the-box when you are using a Frame though.

You could either replace the Frame with a ContentControl:

<ToggleButton x:Name="EditButton" IsChecked="{Binding CanEdit}">Edit</ToggleButton>
<ContentControl>
    <local:Home />
</ContentControl>

Or you could handle the DataContextChanged event for the Frame and set the DataContext of its Content explicitly as suggested by @Joe White here: page.DataContext not inherited from parent Frame?



标签: c# wpf xaml mvvm