2013-08-04 18 views
0

我想要創建某種過濾器,當用戶從應用程序欄中單擊過濾器按鈕時,它將啓動一個帶有列表選擇器的彈出頁面。我搜索了很多方法,但仍然無法實現。CaliburnMicro操作不會觸發數據模板

這裏是我的代碼:

XAML(MainPageView.xaml)

<phone:PhoneApplicationPage.Resources> 
     <DataTemplate x:Key="PivotContentTemplate"> 
      <phone:Pivot Margin="-12,0,0,0" Title="FOREX NEWS" Height="672"> 
       <phone:PivotItem Header="filter" FontFamily="{StaticResource PhoneFontFamilySemiLight}" FontSize="32"> 
        <StackPanel Margin="12,0,0,0"> 
         <toolkit:ListPicker Header="currencies" SelectionMode="Multiple" 
              micro:Message.Attach="[Event SelectionChanged] = [Action OnCurrenciesChanged($eventArgs)]"> 
          <sys:String>gbp</sys:String> 
          <sys:String>eur</sys:String> 
          <sys:String>usd</sys:String> 
         </toolkit:ListPicker>       
        </StackPanel> 
       </phone:PivotItem> 
      </phone:Pivot> 
     </DataTemplate> 
<phone:PhoneApplicationPage.Resources> 

...

還在裏面MainPageView.xaml

<bab:BindableAppBar Grid.Row="2" Mode="Minimized"> 
    <bab:BindableAppBarButton micro:Message.Attach="[Event Click] = [Action ShowFilter($view, $eventArgs]"> 

    </bab:BindableAppBarButton> 
</bab:BindableAppBar> 

MainPageViewModel.cs

public void ShowFilter(object sender, RoutedEventArgs e) 
{ 
    var view= sender as MainPageView; 

    CustomMessageBox messageBox = new CustomMessageBox() 
    { 
     ContentTemplate = (DataTemplate)view.Resources["PivotContentTemplate"], 
     LeftButtonContent = "filter", 
     RightButtonContent = "cancel", 
     IsFullScreen = true // Pivots should always be full-screen. 
    }; 

    messageBox.Dismissed += (s1, e1) => 
    { 
     switch (e1.Result) 
     { 
      case CustomMessageBoxResult.LeftButton: 
       // Do something. 
       break; 
      case CustomMessageBoxResult.RightButton: 
       // Do something. 
       break; 
      case CustomMessageBoxResult.None: 
       // Do something. 
       break; 
      default: 
       break; 
     } 
    }; 

    messageBox.Show(); 
} 

public void OnCurrenciesChanged(SelectionChangedEventArgs e) 
{ 

} 

對於您的信息,我使用Caliburn.Micro和WP工具包的CustomMessageBoxListPicker

我收到異常No target found for method OnCurrenciesChanged。當我在列表選取器中選擇幾個項目並單擊任何按鈕以保存更改時,我只會收到異常。另一件事是OnCurrenciesChanged根本沒有被觸發。

我認爲(根據我讀到目前爲止)每當調用CustomMessageBox時,其操作的datacontext不再指向MainPageViewModel因此它找不到方法。但我不確定如何實際做到這一點。

更多細節: 異常發生,我點擊鼠標左鍵(複選標記) exception_here

更新 到目前爲止,我有嘗試以下後:

<StackPanel Margin="12,0,0,0" DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"> //also tried with Self 

,我也加入這個時我例化messageBox

 var messageBox = new CustomMessageBox() 
     { 
      ContentTemplate = (DataTemplate)view.Resources["PivotContentTemplate"], 
      DataContext = view.DataContext, // added this 
      LeftButtonContent = "filter", 
      RightButtonContent = "cancel", 
      IsFullScreen = true 
     }; 

這個想法是,當創建messsagebox時,datacontext將與視圖實例化時相同。但是,似乎datacontext不會繼承PickerList

回答

2

好吧,所以我設法讓這個工作。解決方案並不美觀,我認爲它首先擊敗了MVVM的目的。

基於http://wp.qmatteoq.com/first-steps-in-caliburn-micro-with-windows-phone-8-how-to-manage-different-datacontext/,模板內DataContext將不同。所以,我需要以某種方式告訴ListPicker使用正確的DataContext

以上鍊接提供的解決方案不適用於我。我認爲這是因爲當在CustomMessageBox內部調用ListPicker時,MainPageViewModel不再可用,或者它看起來不能像異常所建議的那樣找到它。因此,根據問題中的上述代碼示例,即使我將DataContext設置爲CustomMessageBox,但它也不會被ListPicker以某種方式繼承。

這裏是我的解決方案:

 var messageBox = new CustomMessageBox() 
     { 
      Name = "FilterCustomMessageBox", // added this 
      ContentTemplate = (DataTemplate)view.Resources["PivotContentTemplate"], 
      DataContext = view.DataContext, 
      LeftButtonContent = "filter", 
      RightButtonContent = "cancel", 
      IsFullScreen = true 
     }; 

在XAML,我編輯這個

  <toolkit:ListPicker Header="currencies" SelectionMode="Multiple" 
           micro:Action.TargetWithoutContext="{Binding ElementName=FilterCustomMessageBox, Path=DataContext}" 
           micro:Message.Attach="[Event SelectionChanged] = [Action OnCurrenciesChanged($eventArgs)]"> 

這是醜陋的,因爲這兩個ViewModelView需要明確地知道Name。在WPF中,你可以在綁定中執行類似這樣的操作來繼承父/ etc的DataContext,但這不適用於WP。

{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}} 

如果有人有更好的解決方法,請讓我知道!