C# 复选框';使用MVVM在DataTemplate ListBox绑定和触发器中

C# 复选框';使用MVVM在DataTemplate ListBox绑定和触发器中,c#,wpf,mvvm,data-binding,eventtrigger,C#,Wpf,Mvvm,Data Binding,Eventtrigger,我正在学习如何使用MVVM以及如何在WPF应用程序中绑定数据。我在XAML文件中创建了一个自定义CheckedListBox,如下所示: <ListBox x:Name="materialsListBox" ItemsSource="{Binding CustomCheckBox}"> <ListBox.ItemTemplate> <DataTemplate>

我正在学习如何使用MVVM以及如何在WPF应用程序中绑定数据。我在XAML文件中创建了一个自定义CheckedListBox,如下所示:

        <ListBox x:Name="materialsListBox" ItemsSource="{Binding CustomCheckBox}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding Path=IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}" Content="{Binding Item}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

而且我还希望为我选中的每个复选框动态显示一个图像。我知道我需要使用Binding和UpdateSourceTrigger属性,但我不确定如何实现这一点。 我应该在这里添加什么,以便我的应用程序实现我想要的功能

        <Image HorizontalAlignment="Left" Height="100" Margin="432,146,0,0" VerticalAlignment="Top" Width="100"/>

下面是我的ViewModel C#代码的一部分:

    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<CheckedListItem<string>> _customCheckBox;
        public ObservableCollection<CheckedListItem<string>> CustomCheckBox
        {
            set
            {
                _customCheckBox = value;
                OnPropertyChanged();
            }
            get { return _customCheckBox; }
        }

        public class CheckedListItem<T> : ViewModelBase
        {
            private bool _isChecked;
            private T _item;

            public CheckedListItem()
            {
            }

            public CheckedListItem(T item, bool isChecked = false)
            {
                item = _item;
                isChecked = _isChecked;
            }

            public T Item
            {
                set
                {
                    _item = value;
                    OnPropertyChanged();
                }
                get { return _item; }
            }


            public bool IsChecked
            {
                set
                {
                    _isChecked = value;
                    OnPropertyChanged();
                }
                get { return _isChecked; }
            }
        }
...
public类MainViewModel:ViewModelBase
{
私有ObservableCollection\u customCheckBox;
公共ObservableCollection自定义复选框
{
设置
{
_customCheckBox=值;
OnPropertyChanged();
}
获取{return\u customCheckBox;}
}
公共类CheckedListItem:ViewModelBase
{
检查私人住宅;
私人信托基金项目;
公共CheckedListItem()
{
}
公共CheckedListItem(T项,bool isChecked=false)
{
项目=_项目;
isChecked=_isChecked;
}
公共交通项目
{
设置
{
_项目=价值;
OnPropertyChanged();
}
获取{return\u item;}
}
公共场所被检查
{
设置
{
_isChecked=值;
OnPropertyChanged();
}
获取{return\u已检查;}
}
}
...

感谢您的推荐。

执行PropertyChanged事件的一种简单方法是使用ViewModelBase.set的基集,因为它将为您引发已更改的事件

为此,我将视图模型和视图分为2个部分,一个用于主视图,另一个用于结合复选框和图像的视图。您可以使用类似的视图来完成,但这对我来说更简单

查看复选框和图像的模型

public class CheckBoxViewModel : ViewModelBase
{
    private bool isChecked;
    private string imageSource;
    private string imageName;

    public CheckBoxViewModel(string imageSource, string imageName)
    {
        this.ImageSource = imageSource;
        this.ImageName = imageName;

    }
    public ICommand Checked => new RelayCommand<string>(this.OnChecked);

    private void OnChecked(object imageName)
    {

    }
    public string ImageSource
    {
        get { return this.imageSource; }
        set { this.Set(() => this.ImageSource, ref this.imageSource, value); }
    }
    public string ImageName
    {
        get { return this.imageName; }
        set { this.Set(() => this.ImageName, ref this.imageName, value); }
    }

    public bool IsChecked
    {
        get { return this.isChecked; }
        set { this.Set(() => this.IsChecked, ref this.isChecked, value); }
    }
}
公共类CheckBoxViewModel:ViewModelBase
{
私人住宅被检查;
私有字符串图像源;
私有字符串imageName;
public CheckBoxViewModel(字符串imageSource,字符串imageName)
{
this.ImageSource=ImageSource;
this.ImageName=ImageName;
}
public ICommand Checked=>new RelayCommand(this.OnChecked);
已检查的私有void(对象imageName)
{
}
公共字符串图像源
{
获取{返回this.imageSource;}
set{this.set(()=>this.ImageSource,ref this.ImageSource,value);}
}
公共字符串ImageName
{
获取{返回this.imageName;}
set{this.set(()=>this.ImageName,ref this.ImageName,value);}
}
公共场所被检查
{
获取{返回this.isChecked;}
set{this.set(()=>this.IsChecked,ref this.IsChecked,value);}
}
}
主窗口视图模型

public class MainViewModel : ViewModelBase
{
    private ObservableCollection<CheckBoxViewModel> items = new ObservableCollection<CheckBoxViewModel>();

    public ObservableCollection<CheckBoxViewModel> Items => this.items;
    public MainViewModel()
    {
        var view = new CheckBoxViewModel("Image.Jpg", "Image 1");
        this.Items.Add(view);
        var view2 = new CheckBoxViewModel("Image2.Jpg", "Image 2");
        this.Items.Add(view2);
    }
}
public类MainViewModel:ViewModelBase
{
私有ObservableCollection项=新ObservableCollection();
公共ObservableCollection Items=>this.Items;
公共主视图模型()
{
var view=新的CheckBoxViewModel(“Image.Jpg”、“Image 1”);
此.Items.Add(视图);
var view2=新的CheckBoxViewModel(“Image2.Jpg”、“Image2”);
此.Items.Add(视图2);
}
}
复选框和图像视图

<UserControl.Resources>
    <local:MainViewModel x:Key="MainViewModel" />
    <local:MainViewModel x:Key="ViewModel" />
    <local:BoolToVisibility x:Key="BoolToVisibility" />
</UserControl.Resources>
<Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="20*"/>
        <ColumnDefinition Width="201*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <CheckBox Command="{Binding Checked}" HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding Path=IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}" Content="{Binding ImageName}" />
    <Image Grid.Column="1" Source="{Binding ImageSource}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding IsChecked, Converter={StaticResource BoolToVisibility}}" />
</Grid>

主视图

    <Window.Resources>
    <local:MainViewModel x:Key="MainViewModel" />
    <DataTemplate DataType="{x:Type local:CheckBoxViewModel}">
        <local:view/>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListView DataContext="{StaticResource MainViewModel}" ItemsSource="{Binding Items}"/>
</Grid>

这样,主视图模型会将CheckBoxViewModels添加到其项中,然后主视图会自动将子视图添加到列表视图中

值得注意的是图像可见性是如何翻转的。我使用了一个值转换器,您可以将其添加到图像可见性绑定中。它会将真值和假值转换为一种可见性类型

 public class BoolToVisibility : IValueConverter
{
    /// <summary>
    /// Converts a value.
    /// </summary>
    /// <param name="value">The value produced by the binding source.</param>
    /// <param name="targetType">The type of the binding target property.</param>
    /// <param name="parameter">The converter parameter to use.</param>
    /// <param name="culture">The culture to use in the converter.</param>
    /// <returns>A converted value. If the method returns null, the valid null value is used.</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            if ((bool)value)
            {
                return Visibility.Visible;
            }
            else
            {
                return Visibility.Collapsed;
            }
        }

        return Visibility.Collapsed;
    }

    /// <summary>
    /// Converts a value.
    /// </summary>
    /// <param name="value">The value that is produced by the binding target.</param>
    /// <param name="targetType">The type to convert to.</param>
    /// <param name="parameter">The converter parameter to use.</param>
    /// <param name="culture">The culture to use in the converter.</param>
    /// <returns>A converted value. If the method returns null, the valid null value is used.</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}
public类booltovision:IValueConverter
{
/// 
///转换一个值。
/// 
///绑定源生成的值。
///绑定目标属性的类型。
///要使用的转换器参数。
///要在转换器中使用的区域性。
///转换后的值。如果方法返回null,则使用有效的null值。
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
if(值!=null)
{
如果((布尔)值)
{
返回可见性。可见;
}
其他的
{
返回可见性。折叠;
}
}
返回可见性。折叠;
}
/// 
///转换一个值。
/// 
///绑定目标生成的值。
///要转换为的类型。
///要使用的转换器参数。
///要在转换器中使用的区域性。
///转换后的值。如果方法返回null,则使用有效的null值。
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
返回null;
}
}

您希望图像在哪里“动态显示”?