开发过程中难免要使用到消息框,然而系统提供的MessageBox却难以满足许多需求。一、MessageBox的背景颜色无法更改,这就无法满足需求要求的消息框颜色。二、MessageBox的提示形式过于单一,难以满足包含ListPicker、CheckBox等方式的弹出框,而CustomMessageBox的模版中包含了ContentPresenter,可以承载各种各样的内容控件。在多方面考虑之后,于是决定选择Toolkit的CustomMessageBox作为应用的弹出提示框。
然而在使用过程中发现CustomMessageBox还是存在些许问题的。
首先,当应用的SystemTray系统托盘的Opacity(透明度)为0的时候,消息框弹出的时候系统托盘仍然是透明的,很难看有木有啊!
为了处理掉这个问题,不得不对CustomMessageBox进行重载。
class="brush:csharp;gutter:false;"> double oldOpacity; public MyCustomMessageBox(): base() { this.Dismissed += MyCustomMessageBox_Dismissed; } void MyCustomMessageBox_Dismissed(object sender, DismissedEventArgs e) { SystemTray.Opacity = oldOpacity; } public void Show() { oldOpacity = SystemTray.Opacity; SystemTray.Opacity = 1;
this.Show(); }
然而,这还是比较小的问题。需求要求的消息框是要不受系统的主题背景影响的,而CustomMessageBox的遮罩背景却会在手机主题背景为白色的时候,遮罩背景变成透明的淡白色,这与应用自身设计的皮肤太不搭调了,很难看。这要如何处理掉呢?查看了CustomMessageBox的模版,发现模版中并没有有关于遮罩背景的部分。
<Style TargetType="controls:CustomMessageBox"> <Setter Property="VerticalAlignment" Value="Top"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="VerticalContentAlignment" Value="Top"/> <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/> <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/> <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/> <Setter Property="Background" Value="{StaticResource PhoneChromeBrush}"/> <Setter Property="Margin" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="controls:CustomMessageBox"> <Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch"> <Grid Width="480" HorizontalAlignment="Left"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <StackPanel Grid.ColumnSpan="2" Margin="0,0,0,18"> <TextBlock x:Name="TitleTextBlock" Text="{TemplateBinding Title}" Foreground="{TemplateBinding Foreground}" Visibility="Collapsed" Margin="24,16,24,-6" FontFamily="{StaticResource PhoneFontFamilySemiBold}"/> <TextBlock x:Name="CaptionTextBlock" Text="{TemplateBinding Caption}" Foreground="{TemplateBinding Foreground}" Visibility="Collapsed" Margin="24,8,24,0" FontSize="{StaticResource PhoneFontSizeLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" TextWrapping="Wrap" HorizontalAlignment="Left"/> <TextBlock x:Name="MessageTextBlock" Text="{TemplateBinding Message}" Foreground="{TemplateBinding Foreground}" Margin="24,11,24,0" Visibility="Collapsed" FontSize="{StaticResource PhoneFontSizeMedium}" FontFamily="{StaticResource PhoneFontFamilySemiLight}" TextWrapping="Wrap" HorizontalAlignment="Left"/> <ContentPresenter Margin="12,0,0,0"/> </StackPanel> <Button x:Name="LeftButton" Grid.Row="1" Grid.Column="0" Content="{TemplateBinding LeftButtonContent}" IsEnabled="{Binding IsLeftButtonEnabled}" Foreground="{TemplateBinding Foreground}" Margin="12,0,0,12" Visibility="Collapsed" controls:TiltEffect.IsTiltEnabled="True"/> <Button x:Name="RightButton" Grid.Row="1" Grid.Column="1" Content="{TemplateBinding RightButtonContent}" IsEnabled="{Binding IsRightButtonEnabled}" Foreground="{TemplateBinding Foreground}" Margin="0,0,12,12" Visibility="Collapsed" controls:TiltEffect.IsTiltEnabled="True"/> </Grid> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
无奈之中只好去看CustomMessageBox的源码,最终发现遮罩的这一层原来是这样实现的。首先创建一个Grid容器,然后再创建一个Rectangle对象作为遮罩层,并且Fill值为系统的PhoneBackgroundColor这个值。将遮罩层Add到Grid容器中,将弹出框Add到Grid容器中,最后在将Grid容器添加到Popup然后弹出。那么可不可以这样做呢,在后台中找到遮罩的Rectangle,将其Fill固定下来。
public void Show() { oldOpacity = SystemTray.Opacity; SystemTray.Opacity = 1; this.Show(); //获取Grid容器 Grid container = this.Parent as Grid; //可视化树中查找Rectangle遮罩层 Rectangle rec = BV_ToolAPI.FindFirstChildOfType<Rectangle>(container); rec.Fill = new SolidColorBrush(Color.FromArgb(0x99, 0, 0, 0)); }
Ok,这样,CustomMessageBox就不会再根据系统的主题背景颜色而变化了。