1

我的视图可以像带有大约 7 个其他单选按钮的单选按钮一样单击,但我的列表框不会更新它的选定属性,除非我在单选按钮之外单击。

基本上我有一个 AbstractTask 作为我的基础。我有7个儿童班。我希望能够选择这些 AbstractTasks 之一。这就是我所追求的。所以在我的主窗口中我有这个。

<Window x:Class="AdvancedTaskAssigner.View.MainWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:v="clr-namespace:AdvancedTaskAssigner.View"
        Title="MainWindowView" Height="300" Width="300" SizeToContent="Height">
    <DockPanel>
        <TextBlock Text="TextBlock" DockPanel.Dock="Top" />
        <TextBlock Text="{Binding ElementName=listTasks, Path=SelectedItem.Name}" DockPanel.Dock="Top" />

        <ListBox x:Name="listTasks" ItemsSource="{Binding Tasks}" HorizontalContentAlignment="Stretch" SelectedItem="{Binding IsSelected}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <v:AbstractTaskView />
                </DataTemplate>
            </ListBox.ItemTemplate>

        </ListBox>
    </DockPanel>
</Window>

因为这是一个库而不是应用程序,所以我不得不将它放在 MainWindowView 的构造函数中

MainWindowView.xaml.cs

    public MainWindowView()
    {
        InitializeComponent();
        var atvm = new ViewModel.MainWindowViewModel();
        atvm.LoadTasks();
        this.DataContext = atvm;
    }

MainWindowViewModel.cs

class MainWindowViewModel
{
    internal void LoadTasks()
    {
        var assembly = Assembly.GetAssembly(typeof(AbstractTask)).GetTypes().Where(t => t.IsSubclassOf(typeof(AbstractTask)));
        Type[] typelist = GetTypesInNamespace(Assembly.GetAssembly(typeof(AbstractTask)), typeof(AbstractTask));
        foreach (Type t in typelist)
        {
            if(!t.IsAbstract && t.BaseType.Equals(typeof(AbstractTask)))
            {
                tasks.Add(new AbstractTaskViewModel(t));
            }

        }
    }
    private Type[] GetTypesInNamespace(Assembly assembly, Type baseClass)
    {
        return assembly.GetTypes().Where(t => t.IsSubclassOf(baseClass)).ToArray();
    }

    private ObservableCollection<AbstractTaskViewModel> tasks = new ObservableCollection<AbstractTaskViewModel>();

    public ObservableCollection<AbstractTaskViewModel> Tasks
    {
        get { return tasks; }
    }

}

AbstractTaskViewModel.cs

public class AbstractTaskViewModel
{
    public AbstractTaskViewModel(Type task)
    {
        if (!task.IsSubclassOf(typeof(AbstractTask)))
        {
            throw new NotSupportedException(string.Format("{0} is not a subclass of AbstractTask", task.Name));
        }
        Task = task;
    }

    public string Description
    {
        get
        {
            return GetCustomAttribute(0);
        }
    }
    public string Name
    {
        get
        {
            return GetCustomAttribute(1);
        }
    }
    public bool IsSelected{get;set;}

    private string GetCustomAttribute(int index)
    {
        var descriptions = (DescriptionAttribute[])Task.GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (descriptions.Length == 0)
        {
            return null;
        }
        return descriptions[index].Description;
    }

    protected readonly Type Task;
}

AbstractTaskView.xaml

<RadioButton 
    x:Class="AdvancedTaskAssigner.View.AbstractTaskView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" GroupName="AbstractTasks" Background="Transparent" IsChecked="{Binding IsSelected, Mode=TwoWay}">
    <RadioButton.Template>
        <ControlTemplate TargetType="{x:Type RadioButton}">
            <Grid>
                <Border x:Name="MyHead" BorderBrush="Black" BorderThickness="2" CornerRadius="5" Background="LightGray" Margin="20,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Panel.ZIndex="2">
                    <TextBlock Text="{Binding Name}" Margin="5,2" MinWidth="50" />
                </Border>
                <Border x:Name="Myoooo" BorderBrush="Black" BorderThickness="2" CornerRadius="5" Background="Transparent" Margin="0,10,0,0" Panel.ZIndex="1">
                    <TextBlock Text="{Binding Description}" Margin="5,15,5,2" />
                </Border>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter TargetName="MyHead" Property="Background" Value="LightGreen" />
                </Trigger>

            </ControlTemplate.Triggers>

        </ControlTemplate>
    </RadioButton.Template>

</RadioButton>

这就是我得到的..

我希望绿色边框成为所选项目。不是列表框的选定项是什么。底部的文本框是所选项目的名称。 该代码的结果是什么

4

2 回答 2

0

有一些与 RadioButton 的 IsChecked 属性绑定相关的问题。你可以在这里这里阅读它。您可以使用 AbstractTaskView 而不是 RadioButton 应用第一个链接中提供的解决方案。用代码替换 MainWindowView 中的列表框:

<ListBox x:Name="listTasks" ItemsSource="{Binding Tasks}" HorizontalContentAlignment="Stretch">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <v:AbstractTaskView Content="{TemplateBinding Content}"
                             IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

您还必须从AbstractTaskView中删除以下代码部分:

IsChecked="{Binding IsSelected, Mode=TwoWay}"

我希望您不需要设置AbstractTaskViewModel的IsSelected属性。但是如果你这样做了,你可以在后面的AbstractTaskView代码中的Checked事件处理程序中设置它(我知道这不是很好的解决方案)。

于 2013-08-27T00:09:03.483 回答
-1

我看到您将 IsSelected (布尔值)绑定到 SelectedItem (对象)

于 2013-08-26T20:03:07.093 回答