简单的MVVM - 如何注意两个视图模型之间的属性交换

时间:2013-11-28 10:14:54

标签: c# wpf

例如,我写了这段代码:

xaml1:

<UserControl x:Class="Aplikacja_desktopowa.CustomerView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid x:Name="LayoutRoot" Background="White" Height="150" Width="300" 
        DataContext="{Binding Source={StaticResource Locator}, Path=CustomerViewModel}">
        <Button Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Command="{Binding LogowanieCommand}"/>
        <Button Content="Button"  IsEnabled="{Binding IsEnabled}" HorizontalAlignment="Left" Margin="112,104,0,0" VerticalAlignment="Top" Width="76"/>
    </Grid>
</UserControl>

Xaml2:

<Window x:Class="Aplikacja_desktopowa.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:Aplikacja_desktopowa"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding Source={StaticResource Locator}, Path=[MainPageViewModel]}">
    <StackPanel>
        <TextBlock Text="{Binding Path=BannerText}" FontFamily="Verdana" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" />
        <Button Content="Button" IsEnabled="{Binding Source={StaticResource Locator}, Path=CustomerViewModel.IsEnabled}"/>
        <my:CustomerView />
    </StackPanel>
</Window>

使用属性

查看模型
public class CustomerViewModel : INotifyPropertyChanged{
    private DelegateCommand _przycisk;
    public ICommand LogowanieCommand
    {
        get
        {
            if (_przycisk == null)
                _przycisk = new DelegateCommand(funkcja1, funkcja2);
            return _przycisk;
        }
    }

    public void funkcja1()
    {
        MessageBox.Show("Odblokowywanie przycisku");
        IsEnabled = true;
    }
    public bool funkcja2()
    {
        return true;
    }

    private bool _isEnabled;

    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value; 
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

这是这样的:

view1 ({binding IsEnabled) ----- view_model1_with_property_IsEnabled 
                                           |
                                           |
                                           |
                                           |
                                           |
main_view ( with Staticresource view_model1,IsEnabled)

我尝试了一切,但它不起作用;((

如何注意两个xamls中的propertychanged?

问题澄清

好的,所以,我有两个独立的视图模型,wfp中的两个独立视图(简单的mvvm模板)当我点击按钮时,它会将属性IsEnabled设置为true。它的确定,notifypropertychange工作正常。但是当我想在不同的视图中通知属性时(例如,当我在view2中单击按钮时,我想在view1中解锁按钮)

<Button Content="Button" IsEnabled="{Binding Source={StaticResource Locator}, 
Path=CustomerViewModel.IsEnabled}"/>

它不起作用;(我在简单的mvvm中寻找最简单的方法......)


Sheridan,我在ViewModelLocator中创建了一个属性,它就像我想要的那样工作......但是当我实现更大的应用程序时,在ViewModelLocator中我将获得很多方法,是否有更好的解决方案?

2 个答案:

答案 0 :(得分:2)

你可能想看看使用像galasoft的mvvm灯这样的框架,它提供了一个消息传递类,允许你在视图模型之间传递对象。

MVVM Light Messenger - Sending and Registering Objects

答案 1 :(得分:1)

此问题有许多解决方案,但其中一个是使用可以访问其他视图模型的父视图模型。最简单的解决方法是在父视图模型中定义bool IsEnabled属性,然后从两个子视图模型直接绑定到此属性:

<Button Content="Button" IsEnabled="{Binding DataContext.IsEnabled, RelativeSource=
    {RelativeSource AncestorType={x:Type YourXmlNamespacePrefix:YourParentView}}}" />

RelativeSource Binding将在对象中查找名为IsEnabled的属性,该属性设置为此DataContext类型Button控件的父级或祖先的YourParentView 1}}。显然,您需要将名称更新为代码中的名称。