【问题标题】:WP8 - ValidatesOnExceptionsWP8 - ValidatesOnExceptions
【发布时间】:2013-07-15 17:00:05
【问题描述】:

我无法使用 VS2012 for Windows Phone 来实现这一点。如果我使用属性 ValidateOnExceptions=true 创建一个文本框并在设置器中抛出异常,则不会捕获该异常,而只会在调试窗口中出现:

A first chance exception of type 'System.ArgumentException' occurred in PhoneApp1.DLL
An exception of type 'System.ArgumentException' occurred in PhoneApp1.DLL but was not handled in user code
System.Windows.Data Error: Cannot save value from target back to source. BindingExpression: Path='Thingy' DataItem='PhoneApp1.MyContext' (HashCode=38891250); target element is 'System.Windows.Controls.TextBox' (Name=''); target property is 'Text' (type 'System.String').. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: I said don't type 'foo'!
   at PhoneApp1.MyContext.set_Thingy(String value)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at System.Windows.CLRPropertyListener.set_Value(Object value)
   at System.Windows.PropertyAccessPathStep.set_Value(Object value)
   at System.Windows.Data.BindingExpression.UpdateValue().

我做了一个玩具示例来隔离问题 - 这是我的 xaml:

<phone:PhoneApplicationPage
    x:Class="PhoneApp1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:my="clr-namespace:PhoneApp1;assembly=PhoneApp1"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

        <TextBlock Text="Do NOT type 'foo' in this box"/>
      <TextBox Text="{Binding Thingy, Mode=TwoWay,  ValidatesOnExceptions=True}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

        </Grid>

    </Grid>

</phone:PhoneApplicationPage>

我的主页:

/* imports snipped..*/

namespace PhoneApp1 {

  public class MyContext {
    private String _thingy = String.Empty;
    public String Thingy {
      get {
        return _thingy;
      }
      set {
        if (value == "foo") {
          throw new ArgumentException("I said don't type 'foo'!");
        }
        _thingy = value;
      }
    }
    public MyContext() {
    }
  }
  public partial class MainPage : PhoneApplicationPage {


    // Constructor
    public MainPage() {
      InitializeComponent();
      this.DataContext = new MyContext();
    }

  }
}

我已经搜索了这个以寻找线索,但是当 ValidateOnExceptions=true 并且支持 WP8 时,它应该提供视觉反馈似乎非常明确:

http://msdn.microsoft.com/en-us/library/windowsphone/develop/cc278072(v=vs.105).aspx#BKMK_Datavalidation

【问题讨论】:

    标签: c# .net wpf windows-phone-8


    【解决方案1】:

    我们的程序Terminator 使用 IErrorInfo 和朋友验证地理坐标。

    您可能会发现验证机制正在工作,但您需要将正确的样式添加到控件模板中的可视状态管理器中。这是我们的验证文本框样式

      <Style x:Key="ValidatingTextBox" TargetType="TextBox">
        <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
        <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
        <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
        <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
        <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>
        <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>
        <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
        <Setter Property="Padding" Value="2"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="TextBox">
              <Grid Background="Transparent">
                <VisualStateManager.VisualStateGroups>
                  <VisualStateGroup x:Name="ValidationStates">
                    <VisualState x:Name="Valid" >
                      <Storyboard Duration="00:00:01">
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="WarningEllipse">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="WarningText">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualState>
                    <VisualState x:Name="InvalidUnfocused">
                      <Storyboard Duration="00:00:01">
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="WarningEllipse">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <!-- note the warning text is not shown if unfocused -->
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="WarningText">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualState>
                    <VisualState x:Name="InvalidFocused">
                      <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="WarningText">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="WarningEllipse">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualState>
                  </VisualStateGroup>
                  <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal"/>
                    <VisualState x:Name="MouseOver"/>
                    <VisualState x:Name="Disabled">
                      <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualState>
                    <VisualState x:Name="ReadOnly">
                      <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
                          <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                              <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                          </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledOrReadonlyBorder">
                          <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="DisabledOrReadonlyBorder">
                          <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent">
                          <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualState>
                  </VisualStateGroup>
                  <VisualStateGroup x:Name="FocusStates">
                    <VisualState x:Name="Focused">
                      <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="EnabledBorder">
                          <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder">
                          <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Unfocused"/>
                  </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Border x:Name="EnabledBorder"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">
                  <Grid>
                    <Grid.RowDefinitions>
                      <RowDefinition Height="Auto" />
                      <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <ContentControl Grid.Row="0" x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch"
                            Margin="{StaticResource PhoneTextBoxInnerMargin}"
                            Padding="{TemplateBinding Padding}"
                            VerticalContentAlignment="Top"/>
                    <Ellipse Grid.Row="0"
                        x:Name="WarningEllipse"  Visibility="Collapsed"
                        Margin="12,12,12,0"
                        VerticalAlignment="Top"
                        HorizontalAlignment="Right"
                        Width="14" Height="14"
                        Stroke="#40000000" StrokeThickness="2" Fill="Red">
                    </Ellipse>
                    <TextBlock x:Name="WarningText" Grid.Row="1" Foreground="Red"  Visibility="Collapsed" TextWrapping="Wrap"
                            Margin="3,-12,3,0"
                             Text="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                                  Path=(Validation.Errors)[0].ErrorContent, FallbackValue=''}"></TextBlock>
                  </Grid>
                </Border>
                <Border x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent"
                      Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed">
                  <TextBox x:Name="DisabledOrReadonlyContent"
                         Background="Transparent"
                         Foreground="{StaticResource PhoneDisabledBrush}"
                         FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}"
                         FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}"
                         IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}"
                         SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}"
                         TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}"
                         Template="{StaticResource PhoneDisabledTextBoxTemplate}"/>
                </Border>
              </Grid>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-24
      • 1970-01-01
      相关资源
      最近更新 更多