将CheckListBox绑定到ViewModel

时间:2016-11-18 18:19:20

标签: c# wpf xaml mvvm data-binding

我正在使用WPF Toolkit中的CheckListBox并尝试将其绑定到我的ViewModel。除了从控件中获取所选值之外,我还希望能够通过单击按钮来重置它,这将清除任何选择。我坚持如何绑定集合中每个项目的选定或检查状态,但如果我的整个方法都关闭,我也会对此有所了解。

我创建了一个带有字符串描述符和布尔属性的简单类,我打算用它来指示每个复选框的状态......

public class DrugInfluence : INotifyPropertyChanged
{
    public string Impairment { get; set; }
    private bool isChecked;

    public bool IsChecked
    {
        get { return isChecked; }
        set
        {
            if(isChecked != value)
            {
                isChecked = value;
                OnPropertyChanged("IsChecked");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

ViewModel中的一个名为ImpairmentList的DrugInfluence对象的集合,我想绑定到CheckListBox控件的迭代...

    public List<DrugInfluence> ImpairmentList
    {
        get
        {
            return impairmentList;
        }
        set
        {
            if(impairmentList != value)
            {
                impairmentList = value;
                NotifyPropertyChanged("ImpairmentList");
            }
        }            
    }

我正在使用XAML将ViewModel绑定到CheckListBox控件......

        <sdk:CheckListBox Margin="6"
                          ItemsSource="{Binding ImpairmentList}"   
                          DisplayMemberPath="Impairment"
                          SelectedMemberPath="IsChecked"
                          SelectedItemsOverride="{Binding SelectedImpairments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        </sdk:CheckListBox>

1 个答案:

答案 0 :(得分:0)

this是您正在使用的控件吗?如果是这样,看起来SelectedMemberPath是您要绑定到的属性。如果要以编程方式检查/取消选中,则还需要在IsChecked属性更改时引发事件。例如,

#include <complex>
#include <functional>
#include <iostream>

#include <boost/mpi.hpp>
#include <boost/mpi/operations.hpp>
#include <boost/serialization/complex.hpp>

// tested with GCC 6.2.0, OpenMPI 2.0.1, boost 1.62.0
// mpic++ -lboost_mpi -lboost_serialization boost-mpi-complex.cpp

using dcomplex = std::complex<double>;
using dcplus = std::plus<dcomplex>;

////////////////////////////////////////////////////////////////////////////////
// How to pass assertions (1) to (5) below?
////////////////////////////////////////////////////////////////////////////////

// (A): documented, but fails assertions (2) and (3)
// if (2) and (3) are removed with this OPTION: segmentation fault at runtime
//BOOST_IS_MPI_DATATYPE(dcomplex)

// (B): documented, but same problems as (A)
namespace boost::mpi {
//template<> struct is_mpi_datatype<dcomplex> : boost::mpl::true_ {};
}

// (C): works, but not documented(?) and has `INTERNAL ONLY` comment in source
namespace boost::mpi {
//BOOST_MPI_DATATYPE(dcomplex, MPI_DOUBLE_COMPLEX, complex);
}

// (D): works, equivalent to (C)
// BUT if `is_mpi_complex_datatype` is specialized without `get_mpi_datatype`
// then compilation is fine with all assertions, but running yields segfault
namespace boost::mpi {
//template<> inline MPI_Datatype get_mpi_datatype<dcomplex>(const dcomplex&) {
//  return MPI_DOUBLE_COMPLEX;
//}
//template<> struct is_mpi_complex_datatype<dcomplex> : boost::mpl::true_ {};
}

// optional; works as expected for assertion (4)
namespace boost::mpi {
template<> struct is_commutative<dcplus, dcomplex> : mpl::true_ {};
}

// If these assertions are removed and none of (A) to (D) is activated then
// everything works as expected, but I would like to optimize serialization
static_assert(boost::mpi::is_mpi_datatype<dcomplex>{});                   // (1)
static_assert(boost::mpi::is_mpi_builtin_datatype<dcomplex>{});           // (2)

static_assert(boost::mpi::is_mpi_op<dcplus, dcomplex>{});                 // (3)
static_assert(boost::mpi::is_commutative<dcplus, dcomplex>{});            // (4)

static_assert(boost::serialization::is_bitwise_serializable<dcomplex>{}); // (5)

int main() {
  boost::mpi::environment env{};
  boost::mpi::communicator world{};

  constexpr size_t N = 4;

  dcomplex data[N]{};
  if(0 == world.rank()) {
    for(size_t i=0; i<N; ++i) data[i] = dcomplex{double(i), 0.0};
  }
  if(1 == world.rank()) {
    for(size_t i=0; i<N; ++i) data[i] = dcomplex{0.0, double(N+i)};
  }

  all_reduce(world, boost::mpi::inplace(data), N, dcplus{});

  if(0 == world.rank()) {
    for(auto&& x : data) std::cout << x << std::endl;
  }

  return 0;
}

然后实现其余的INotifyPropertyChanged成员