首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有多模型实例的WPF MVVM

问具有多模型实例的WPF MVVM
EN

Stack Overflow用户
提问于 2017-05-14 13:44:33
回答 1查看 344关注 0票数 0

有很多MVVM示例,但是我不能将其中一个应用到我的案例中,因为有相同类的的几个实例。此外,我需要直接操作模型,以便我可以订阅一些观察者的他们的可观测的。

我为这个问题简化了我的案子。我的模型有三个类: Lamp、Switch和Grid。它们可以通过一个观察者/可观察的机制进行交互。基本上,激活一个开关开关,打开/关闭所有连接到同一栅格的灯。

我想要创建一个窗口来显示这些类的特定用法。应该有按钮的绑定切换和TextBlock的绑定到灯的。

如何将每个实例绑定到我为其准备的UI组件?

下面是一个简单的案例,我想为以下内容构建一个UI:

代码语言:javascript
复制
Grid entranceGrid = new Grid("Entrance Grid");
Lamp hallLamp = new Lamp("Hall Lamp");
Lamp stairsLamp = new Lamp("Stairs Lamp");
Switch downSwitch = new Switch("Downstair Switch");
Switch upSwitch = new Switch("Upstair Switch");

downSwitch.Subscribe(entranceGrid);
upSwitch.Subscribe(entranceGrid);
entranceGrid.Subscribe(hallLamp);
entranceGrid.Subscribe(stairsLamp);

// Below are four instances I'd like to bind to some UI component.
LampViewModel hallLampVM = new LampViewModel(hallLamp);
LampViewModel stairsLampVM = new LampViewModel(stairsLamp);
SwitchViewModel downSwitchVM = new downSwitchVM(downSwitch);
SwitchViewModel upSwitchVM = new downSwitchVM(upSwitch);

这是我的完整代码,如果你想玩的话(VS 2017)

EN

回答 1

Stack Overflow用户

发布于 2017-05-14 16:50:12

这个答案是丑陋的,但它确实有效,也许它会帮助别人得到更好的东西。

我将暂时实施这个解决方案。也许,我会做一些更好的事情来处理NotifyPropertyChanged。

XAML窗口:

代码语言:javascript
复制
<Window.DataContext>
    <vm:MainViewModel />
</Window.DataContext>
<Grid Margin="0,0,0,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="2*" />
        <RowDefinition Height="3*" />
        <RowDefinition Height="2*" />
    </Grid.RowDefinitions>
    <GroupBox Grid.Row="0" Header="Entrée">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Row="0" Grid.Column="0" Text="Hall d'entrée"/>
            <TextBlock Grid.Row="1" Grid.Column="0" Text="Escalier"/>

            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TxtHallLamp}"/>
            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding TxtStairsLamp}"/>

            <Button Grid.Row="0" Grid.Column="2" Content="rez" Command="{Binding DownSwitchCommand}"/>
            <Button Grid.Row="1" Grid.Column="2" Content="1er" Command="{Binding UpSwitchCommand}"/>
        </Grid>
    </GroupBox>
    [Few lines you don't need]
</Grid>

沿着ViewModelBase沿着MainViewModel:

代码语言:javascript
复制
public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public bool NotifyPropertyChanged<T>(ref T variable, T value, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(variable, value)) return false;

        variable = value;
        NotifyPropertyChanged(propertyName);
        return true;
    }
}


class MainViewModel : ViewModelBase
{
    private Lamp _HallLamp, _StairsLamp;
    private Switch _DownSwitch, _UpSwitch;

    private IRelayCommand _DownSwitchCommand, _UpSwitchCommand;

    public MainViewModel()
    {
        #region entrance

        Grid entranceGrid = new Grid("Entrance Grid");
        _HallLamp = new Lamp("Hall Lamp");
        _StairsLamp = new Lamp("Stairs Lamp");
        _DownSwitch = new Switch("Downstair Switch");
        _UpSwitch = new Switch("Upstair Switch");

        _DownSwitch.Subscribe(entranceGrid);
        _UpSwitch.Subscribe(entranceGrid);
        entranceGrid.Subscribe(_HallLamp);
        entranceGrid.Subscribe(_StairsLamp);

        #endregion // entrance
    }

    private string LampToTxt(Lamp lamp)
    {
        return lamp.Light ? "ON" : "OFF";
    }

    public string TxtHallLamp
    {
        get
        {
            return LampToTxt(_HallLamp);
        }
    }

    public string TxtStairsLamp
    {
        get
        {
            return LampToTxt(_StairsLamp);
        }
    }

    private void NotifyEntranceGridPropertyChanged()
    {
        NotifyPropertyChanged(nameof(TxtHallLamp));
        NotifyPropertyChanged(nameof(TxtStairsLamp));
    }

    public IRelayCommand DownSwitchCommand
    {
        get
        {
            return _DownSwitchCommand ?? (_DownSwitchCommand = new RelayCommand(
                () => {
                    _DownSwitch.Press();
                    NotifyEntranceGridPropertyChanged();
                },
                () => true));
        }
    }

    public IRelayCommand UpSwitchCommand
    {
        get
        {
            return _UpSwitchCommand ?? (_UpSwitchCommand = new RelayCommand(
                () => {
                    _UpSwitch.Press();
                    NotifyEntranceGridPropertyChanged();
                },
                () => true));
        }
    }
}

以及类IRelayCommand上的接口RelayCommand:

代码语言:javascript
复制
public interface IRelayCommand : ICommand
{
    void RaiseCanExecuteChanged();
}

class RelayCommand : IRelayCommand
{

    private Action _Execute;
    private Func<bool> _CanExecute;
    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action Execute) : this(Execute, null)
    {

    }

    public RelayCommand(Action Execute, Func<bool> CanExecute)
    {
        if (Execute == null)
            throw new ArgumentNullException();

        _Execute = Execute;
        _CanExecute = CanExecute;
    }

    public bool CanExecute(object parameter)
    {
        return (_CanExecute == null) ? true : _CanExecute();
    }

    public void Execute(object parameter)
    {
        _Execute();
    }

    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43964587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档