2012-08-09 45 views
0

我使用Caliburn Micro開發適用於Windows Phone 7的應用程序。Caliburn Micro中動作調用的不可預知的行爲

聽到是應用程序主要部分的代碼。

部分

的MainView

<Grid x:Name="LayoutRoot" Background="Transparent"> 
    <controls:Panorama> 
     <controls:PanoramaItem x:Name="SubPanoramaItem" 
           DataContext="{Binding SubViewModel}"> 
      <StackPanel> 

       <toolkit:ListPicker ExpansionMode="FullScreenOnly" 
            ItemsSource="{Binding DataModeList}"> 

        <toolkit:ListPicker.ItemTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding Tag}" /> 
         </DataTemplate> 
        </toolkit:ListPicker.ItemTemplate> 

        <toolkit:ListPicker.FullModeItemTemplate> 
         <DataTemplate> 

          <StackPanel x:Name="item" 
             Margin="5, 24, 0, 24" 
             cal:Action.TargetWithoutContext="{Binding ElementName=SubPanoramaItem, 
                        Path=DataContext}" 
             cal:Message.Attach="[Event Tap] = [Action Tap($dataContext)]" 
             Orientation="Horizontal"> 

           <TextBlock FontSize="40" 
              Text="{Binding PopupText}" /> 
          </StackPanel> 

         </DataTemplate> 
        </toolkit:ListPicker.FullModeItemTemplate> 

       </toolkit:ListPicker> 

      </StackPanel> 
     </controls:PanoramaItem> 

     <!-- Some other code --> 
    </controls:Panorama> 
</Grid> 

MainViewModel

public class MainViewModel: Screen 
{ 
    public SubViewModel SubViewModel { get; private set; } 

    public MainViewModel(SubViewModel subViewModel) 
    { 
     SubViewModel = subViewModel; 
    } 

    // some other code 
} 

SubViewModel

public class SearchViewModel : Screen 
{ 
    private ObservableCollection<DateModeItem> _dataModeList = 
     new ObservableCollection<DateModeItem>() 
      { 
       new DataItem 
       { PopupText = "Item 1" }, 
       new DataItem 
       { PopupText = "Item 2" }, 
       new DataItem 
       { PopupText = "Item 3" }, 
       new DataItem 
       { PopupText = "Item 4" } 
      }; 

    public ObservableCollection<DateModeItem> DataModeList 
    { 
     get 
     { 
      return _dataModeList; 
     } 

     private set { _dataModeList = value; } 
    } 

    public void Tap(object dataContext) 
    { 
     var item = dataContext as DataItem; 
     if (item != null) 
     { 
      var r = new Random(); 
      switch (item.PopupText) 
      { 
       case "Item 1": 
        item.Tag = r.Next(5); 
        break; 
       case "Item 2": 
        item.Tag = r.Next(5, 10); 
        break; 
       case "Item 3": 
        item.Tag = r.Next(10, 15); 
        break; 
       case "Item 4": 
        item.Tag = r.Next(15, 20); 
        break; 
      } 
     } 
    } 
} 

的DataItem

public class DataItem 
{ 
    public string PopupText { get; set; } 
    public int Tag { get; set; } 
} 

正如你可以看到我已經連接到行動中ListPicker DataTemplate中的每個StackPanel中。當在列表中的項目上點擊時,必須生成新的隨機標籤。這個標籤被插入到ListPicker的文本框中。

而這種行爲表現得非常奇怪。當我點擊1,2和4項時,什麼也沒有發生。當我點擊3項時,應用程序會拋出異常 - 「沒有找到方法點擊的目標」。而當我使用Silverlight Toolkit的ListPicker時會發生這種情況。

我也從Telerik的RadConrols庫中找到了RadListPicker。當我使用它時,動作方法的調用是不可預知的。有時動作調用方法正確。有時什麼都沒有發生。我可以肯定地說 - 通過點擊最後一個項目,它不會以正確的方式工作。

這是怎麼回事?我無法理解。

附加信息:

我做了所有不必要的東西清潔從我的應用程序,只留下我在以前的帖子上述代碼。

現在,當我使用ListPicker時 - 根本沒有任何反應。列表不響應點擊。有時app會拋出「找不到方法Tap」的異常。當我使用RadListPicker時 - 幾乎總是沒有調用操作,有時(很少)調用正確。

回答

1

當您使用ListPicker時,您需要在Order中添加一些ElementConventions以將視圖的動作綁定到ViewModel。

添加綁定約定可以在AppBootstrapper類中完成。代碼可能類似於:

protected override void Configure() 
    { 
     ConventionManager.AddElementConvention<ListPicker>(ListPicker.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding = 
     (viewModelType, path, property, element, convention) => { 
     if (ConventionManager.GetElementConvention(typeof(ItemsControl)).ApplyBinding(viewModelType, path, property, element, convention)) 
     { 
      ConventionManager.ConfigureSelectedItem(element, ListPicker.SelectedItemProperty, viewModelType, path); 
      return true; 
     } 
     return false; 
    }; }