代码之家  ›  专栏  ›  技术社区  ›  Jiew Meng

C 35;/MVVM:基于另一个控件的属性启用/禁用按钮

  •  0
  • Jiew Meng  · 技术社区  · 15 年前

    假设我有一个显示各种类型数据的tab控件,例如 EditorTabViewModel , PreviewTabViewModel 两者都继承自 TabViewModel tutorial on MSDN

    我想根据活动选项卡启用按钮,是否 编辑器视图模型 预览视图模型

    更新

    public ICommand EditorCommand
    {
        get
        {
            if (_editorCommand == null) {
                _editorCommand = new RelayCommand(() =>
                {
                    MessageBox.Show("Editor");
                }, () =>
                {
                    var enabled = true;
                    var viewSource = CollectionViewSource.GetDefaultView(Tabs);
                    viewSource.CurrentChanged += (o, e) =>
                    {
                        if (viewSource.CurrentItem is EditorTabViewModel)
                        {
                            enabled = false;
                        }
                    };
                    return enabled;
                });
            }
            return _editorCommand;
        }
    }
    

    更新2

    public ICommand PreviewCommand
    {
        get
        {
            if (_previewCommand == null) {
                _previewCommand = new RelayCommand(() =>
                {
                    MessageBox.Show("Preview");
                }, () =>
                {
                    var viewSource = CollectionViewSource.GetDefaultView(Tabs);
                    var enabled = viewSource.CurrentItem is EditorTabViewModel;
                    viewSource.CurrentChanged += (o, e) =>
                    {
                        CommandManager.InvalidateRequerySuggested();
                    };
                    return enabled;
                });
            }
            return _previewCommand;
        }
    }
    
    4 回复  |  直到 15 年前
        1
  •  3
  •   Steve Greatrex    15 年前

    我建议你创建一个 ICommand ICollectionView CurrentChanged 事件,以确定是否应启用它,并引发 CanExecuteChanged

    class MyCommand : ICommand
    {
        private bool _isEnabled = true;
    
        public MyCommand(MyTopLevelViewModel viewModel)
        {
            var viewSource = CollectionViewSource.GetDefaultView(viewModel.Tabs);
            viewSource.CurrentChanged += (o,e) =>
                {
                    _isEnabled = (viewSource.CurrentItem is EditorTabViewModel); //or however you want to decide
    
                    if (this.CanExecuteChanged != null) 
                         this.CanExecuteChanged(this, EventArgs.Empty);
    
                };
        }
    
        public void Execute(object parameter) { /*...*/ }
    
        public bool CanExecute(object parameter) { return _isEnabled; }
    
        public event EventHandler CanExecuteChanged;
    }
    

    注意:您需要设置 IsSyncronizedWithCurrentItem

    <TabControl IsSynchronizedWithCurrentItem="True" />
    
        2
  •  0
  •   Preet Sangha    15 年前

    你可以从任何东西转换成任何东西。传入活动表单可以确定类型,从而返回true/false以绑定到buttons enabled属性。

        3
  •  0
  •   Carles Company    15 年前

    public bool EditorTabVisible{
        get{
            return GetActiveWorkspace() is EditorTabViewModel;
        }
    }
    

    OnPropertyChanged("EditorTabVisible");
    

    然后可以将按钮的IsEnabled属性绑定到此属性。

    我不知道是否有更好的方法,但这对我有效。

        4
  •  0
  •   TerrorAustralis    15 年前

    做两个视图(数据模板)可能更符合MVVM。只需在控制资源中将它们作为泛型执行。

    <TabControl>
    <TabControl.Resources>
        <DataTemplate DataType="EditorTabViewModel">
             <Button Content="Enabled for Editor only" IsEnabled=True Command=SomeCommand />
             <Button Content="Enabled for Preview only" IsEnabled=False Command=SomeCommand />
        </DataTemplate/>
        <DataTemplate DataType="PreviewTabViewModel">
            <Button Content="Enabled for Editor only" IsEnabled=False Command=SomeCommand />
            <Button Content="Enabled for Preview only" IsEnabled=True Command=SomeCommand />
        </DataTemplate>
    </TabControl.Resources>
    <TabControl.ItemTemplate>
        <DataTemplate DataType="TabViewModel">
            <TextBlock Text="{Binding SomeValueToShowAsHeader}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    </TabControl>
    

    所以所有的标签都有相同的标签头,因为itemtemplate是显式定义的。但由于ContentTemplates没有显式定义,因此当控件查找内容的模板时,它将为其提供域的默认模板。由于我们定义了两个默认模板,一个用于EditorTabViewModel,一个用于PreviewTabViewModel,当遇到其中一个模板时,它会将其分配给该数据模板。这将导致选项卡集合中显示两个不同的显示。我还没有完全尝试过tab-viewmodel,所以如果它不能按预期工作,请告诉我。