首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用MVVM的DataTemplate ListBox绑定和触发器中的复选框

使用MVVM的DataTemplate ListBox绑定和触发器中的复选框
EN

Stack Overflow用户
提问于 2020-03-16 04:41:24
回答 1查看 210关注 0票数 2

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

代码语言:javascript
运行
复制
        <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>

而且我还想为我检查的每个CheckBox动态显示一个单独的图像。我知道我需要使用绑定和UpdateSourceTrigger属性,但我不确定如何实现这一点。我应该在这里添加什么,以便我的应用程序可以执行我想要的操作?

代码语言:javascript
运行
复制
        <Image HorizontalAlignment="Left" Height="100" Margin="432,146,0,0" VerticalAlignment="Top" Width="100"/>

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

代码语言:javascript
运行
复制
    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; }
            }
        }
...

感谢您的推荐。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-30 01:51:16

处理更改事件的一种简单方法是使用ViewModelBase this.Set的基集,因为它将为您引发ProperyChanged事件。

为此,我将视图模型和视图分成两部分,一个用于主视图,另一个用于组合复选框和图像的视图。你可以像你拥有的那样做,但这对我来说更容易。

CheckBox和图像的视图模型

代码语言:javascript
运行
复制
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); }
    }
}

主窗口视图模型

代码语言:javascript
运行
复制
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);
    }
}

复选框和图像视图

代码语言:javascript
运行
复制
<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>

主视图

代码语言:javascript
运行
复制
    <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添加到其项目中,然后主视图会自动将子视图添加到列表视图中。

值得注意的是图像的可见性是如何翻转的。我使用了您添加到Images visibility绑定中的值转换器。它会将true false值转换为可见性类型。

代码语言:javascript
运行
复制
 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;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60697465

复制
相关文章

相似问题

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