Checkbox上的双重绑定

时间:2016-08-01 14:08:35

标签: c# .net wpf mvvm

我有一个使用MVVM的WPF应用程序。我将IsChecked值绑定到我的ViewModel上的模型实例上的布尔值。我还需要将ViewModel上的方法绑定到Checked和Unchecked事件。 (这样我就可以跟踪未保存的更改并更改背景,以便为我的用户提供保存需要的可视指示。我尝试过:

<CheckBox 
    Content="Enable" 
    Margin="5" 
    IsChecked="{Binding Enabled}" 
    Checked="{Binding ScheduleChanged}" 
    Unchecked="{Binding ScheduleChanged}"
    />

但是我在System.Windows.Data.Binding&#39;上获得了“提供”值。抛出异常。&#39;错误。建议?

以下是我正在使用的模型:

    public class Schedule : IEquatable<Schedule>
{
    private DateTime _scheduledStart;
    private DateTime _scheduledEnd;
    private bool _enabled;
    private string _url;
    public DateTime ScheduledStart
    {
        get { return _scheduledStart; }
        set
        {
            _scheduledStart = value;
        }
    }
    public DateTime ScheduledEnd
    {
        get { return _scheduledEnd; }
        set
        {
            if(value < ScheduledStart)
            {
                throw new ArgumentException("Scheduled End cannot be earlier than Scheduled Start.");
            }
            else
            {
                _scheduledEnd = value;
            }
        }
    }
    public bool Enabled
    {
        get { return _enabled; }
        set { _enabled = value; }
    }
    public string Url
    {
        get { return _url; }
        set { _url = value; }
    }

    public bool Equals(Schedule other)
    {
        if(this.ScheduledStart == other.ScheduledStart && this.ScheduledEnd == other.ScheduledEnd 
            && this.Enabled == other.Enabled && this.Url == other.Url)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

我的viewModel包含一个具有ObservableCollection的属性。 ItemsControl绑定到集合并生成列表。所以我的ViewModel知道我的Model实例,但不知道哪一个,我不会想。

2 个答案:

答案 0 :(得分:1)

CheckedUnchecked是事件,因此您无法像IsChecked那样绑定它们,这是一个属性。在更高的层次上,您的视图模型也可能不明白视图上的复选框。

我会在视图模型上创建一个事件,当Enabled被更改时触发,你可以订阅并以任何你喜欢的方式处理它。

private bool _enabled;

public bool Enabled
{
    get
    {
        return _enabled;
    }
    set
    {
        if (_enabled != value)
        {
            _enabled = value;
            RaisePropertyChanged("Enabled");
            if (EnabledChanged != null)
            {
                EnabledChanged(this, EventArgs.Empty);
            }
        }
    }
}

public event EventHandler EnabledChanged;
// constructor
public ViewModel()
{
    this.EnabledChanged += This_EnabledChanged;
}

private This_EnabledChanged(object sender, EventArgs e)
{
    // do stuff here
}

答案 1 :(得分:0)

你应该能够在setd中为Enabled ...

处理这个问题
public class MyViewModel : ViewModelBase
{

    private bool _isDirty;
    private bool _enabled;

    public MyViewModel()
    {
        SaveCommand = new RelayCommand(Save, CanSave);
    }

    public ICommand SaveCommand { get; }

    private void Save() 
    {
       //TODO: Add your saving logic
    }

    private bool CanSave()
    {
        return IsDirty;
    }

    public bool IsDirty
    {  
       get { return _isDirty; }
       private set 
       {
           if (_isDirty != value) 
           {
               RaisePropertyChanged(); 
           }
       }
    }

    public bool Enabled 
    {
        get { return _enabled; }
        set
        {
           if (_enabled != value)
           {
               _enabled = value;

               IsDirty = true;
           }

           //Whatever code you need to raise the INotifyPropertyChanged.PropertyChanged event
           RaisePropertyChanged();
        }
    }
}

您收到绑定错误,因为您无法将控件事件直接绑定到方法调用。

修改:添加了更完整的示例。

该示例使用MVVM Lite framework,但该方法适用于任何MVVM实现。