CaliburnMicro操作不会触发数据模板
我想要创建某种过滤器,当用户从应用程序栏中单击过滤器按钮时,它将启动一个带有列表选择器的弹出页面。我搜索了很多方法,但仍然无法实现。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工具包的CustomMessageBox
和ListPicker
。
我收到异常No target found for method OnCurrenciesChanged
。当我在列表选取器中选择几个项目并单击任何按钮以保存更改时,我只会收到异常。另一件事是OnCurrenciesChanged
根本没有被触发。
我认为(根据我读到目前为止)每当调用CustomMessageBox
时,其操作的datacontext不再指向MainPageViewModel
因此它找不到方法。但我不确定如何实际做到这一点。
更多细节: 异常发生,我点击鼠标左键(复选标记)
更新 到目前为止,我有尝试以下后:
<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
好吧,所以我设法让这个工作。解决方案并不美观,我认为它首先击败了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)]">
这是丑陋的,因为这两个ViewModel
和View
需要明确地知道Name
。在WPF中,你可以在绑定中执行类似这样的操作来继承父/ etc的DataContext,但这不适用于WP。
{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}
如果有人有更好的解决方法,请让我知道!