2013-08-26 36 views
1

我不知道我在做什麼錯。我想我可能會讓我的ViewModel出錯,但我感到非常沮喪,因爲它不起作用。到目前爲止,我得到的最接近的是,我的視圖可以像一個單選按鈕一樣點擊,其中有大約7個這樣的單選按鈕。但我的列表框沒有更新它的選定屬性,除非我單擊我的單選按鈕外。綁定RadioButton.IsChecked與Listbox.SelectedItem

因爲我是MVVM整體新手,所以我可能會做這個錯誤。我在某處找到了一個聯繫簿示例,並將其用作我的嚮導。基本上我有一個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> 

這就是我得到..它是令人沮喪!我希望綠色邊框是選定的項目。而不是Listbox的Selected項目是什麼。底部文本框是所選項目的名稱。 What the outcome of that code is

回答

0

我看到你綁定IsSelected(布爾)到的SelectedItem(對象)

+0

這是最新的嘗試使其工作,我也嘗試了其他一些事情。 –

0

有相關的綁定單選按鈕的財產器isChecked一些問題。你可以閱讀它herehere。您可以使用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}" 

我希望你不需要IsSelected財產要設置的AbstractTaskViewModel。但如果你這樣做,你可以設置它在檢查事件處理程序在AbstractTaskView後面的代碼(我知道這不是漂亮的解決方案)。