2016-10-11 6 views
1

ICommand型のDependencyPropertyをバインドする際に問題があります。 これは私のカスタムユーザーコントロールです:UWP ICommand DependencyPropertyキャストエラー

<UserControl x:Class="HexEditor.Controls.NavButton" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="using:HexEditor.Controls" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      d:DesignHeight="300" 
      d:DesignWidth="400" 
      DataContext="{Binding RelativeSource={RelativeSource Self}}" 
      mc:Ignorable="d"> 

    <ToggleButton x:Name="toggleWrap" 
        Width="140" 
        Height="48" 
        Background="Transparent" 
        BorderThickness="0" 
        Command="{Binding Command}" 
        CommandParameter="{Binding CommandParameter}" 
        IsChecked="{Binding IsChecked}"> 
     <Grid Width="140"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <FontIcon Margin="6,0,0,0" 
         Glyph="{Binding Icon}" /> 
      <TextBlock Grid.Column="1" 
         Margin="32,0,0,0" 
         Text="{Binding Title}" /> 
     </Grid> 
    </ToggleButton> 
</UserControl> 

は、これは私のコントロールの背後にあるコードです:

public sealed partial class NavButton : UserControl 
    { 
     public NavButton() 
     { 
      this.InitializeComponent(); 
     } 

     public static readonly DependencyProperty IconProperty = 
      DependencyProperty.Register("Icon", typeof(string), typeof(FontIcon), new PropertyMetadata("")); 

     public static readonly DependencyProperty TitleProperty = 
      DependencyProperty.Register("Title", typeof(string), typeof(TextBlock), new PropertyMetadata("")); 

     public static readonly DependencyProperty IsCheckedProperty = 
      DependencyProperty.Register("IsChecked", typeof(bool), typeof(ToggleButton), new PropertyMetadata("")); 

     public static readonly DependencyProperty CommandProperty = 
      DependencyProperty.Register("Command", typeof(ICommand), typeof(ToggleButton), new PropertyMetadata("")); 

     public static readonly DependencyProperty CommandParameterProperty = 
      DependencyProperty.Register("CommandParameter", typeof(object), typeof(ToggleButton), new PropertyMetadata("")); 

     public string Icon 
     { 
      get { return (string)GetValue(IconProperty); } 
      set { SetValue(IconProperty, value); } 
     } 

     public string Title 
     { 
      get { return (string)GetValue(TitleProperty); } 
      set { SetValue(TitleProperty, value); } 
     } 

     public bool IsChecked 
     { 
      get { return Convert.ToBoolean(GetValue(IsCheckedProperty)); } 
      set { SetValue(IsCheckedProperty, value); } 
     } 

     public ICommand Command 
     { 
      get { return (ICommand)GetValue(CommandProperty); } 
      set { SetValue(CommandProperty, value); } 
     } 

     public object CommandParameter 
     { 
      get { return GetValue(CommandParameterProperty); } 
      set { SetValue(CommandParameterProperty, value); } 
     } 
    } 

そして、これは私が私のコントロールを使用するページです。

<UserControl x:Class="HexEditor.Common.RootFrame" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:Controls="using:HexEditor.Controls" 
      xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core" 
      xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="using:HexEditor.Common" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      d:DesignHeight="300" 
      d:DesignWidth="400" 
      DataContext="{Binding CommonViewModel, 
            Source={StaticResource Locator}}" 
      mc:Ignorable="d"> 
    <Grid Background="White"> 
     <SplitView x:Name="navSplitView" 
        Width="Auto" 
        DisplayMode="CompactOverlay" 
        OpenPaneLength="140"> 
      <SplitView.Pane> 
       <StackPanel> 
        <ToggleButton x:Name="hamBtn" 
            Width="48" 
            Height="48" 
            BorderThickness="0"> 
         <FontIcon Glyph="&#xE700;" /> 
        </ToggleButton> 
        <Controls:NavButton Title="Home" 
             Command="{Binding NavigationCommand}" 
             CommandParameter="HomePage" 
             Icon="&#59407;" 
             IsChecked="True" /> 
        <Controls:NavButton Title="Settings" 
             Command="{Binding NavigationCommand}" 
             CommandParameter="SettingsPage" 
             Icon="&#59155;" 
             IsChecked="False" /> 
       </StackPanel> 
      </SplitView.Pane> 
      <SplitView.Content> 
       <Frame x:Name="NavFrame" /> 
      </SplitView.Content> 
      <Interactivity:Interaction.Behaviors> 
       <Interactions:DataTriggerBehavior Binding="{Binding IsChecked, 
                    ElementName=hamBtn}" 
                Value="True"> 
        <Interactions:ChangePropertyAction PropertyName="IsPaneOpen" 
                 TargetObject="{Binding ElementName=navSplitView}" 
                 Value="True" /> 
       </Interactions:DataTriggerBehavior> 
       <Interactions:DataTriggerBehavior Binding="{Binding IsChecked, 
                    ElementName=hamBtn}" 
                Value="False"> 
        <Interactions:ChangePropertyAction PropertyName="IsPaneOpen" 
                 TargetObject="{Binding ElementName=navSplitView}" 
                 Value="False" /> 
       </Interactions:DataTriggerBehavior> 
      </Interactivity:Interaction.Behaviors> 
     </SplitView> 
    </Grid> 

</UserControl> 

はここですViewModel:

public class CommonViewModel : ViewModelBase 
    { 
     public CommonViewModel() 
     { 
      this.NavigationCommand = new RelayCommand<NavigationSource>(this.ExecuteNavigationCommand); 
     } 

     public ICommand NavigationCommand { get; private set; } 

     private void ExecuteNavigationCommand(NavigationSource state) 
     { 
      NavigationProvider.Instance.NavigateTo(state); 
     } 
    } 

コンパイル時に例外が表示されます。

Exception thrown: 'System.InvalidCastException' in HexEditor.exe 
'HexEditor.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Users\Root\documents\visual studio 2015\Projects\HexEditor\HexEditor\bin\x86\Debug\AppX\System.Resources.ResourceManager.dll'. Module was built without symbols. 
Exception thrown: 'Windows.UI.Xaml.Markup.XamlParseException' in HexEditor.exe 
WinRT information: Failed to assign to property 'HexEditor.Controls.NavButton.Command'. [Line: 29 Position: 41] 
An exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in HexEditor.exe but was not handled in user code 
WinRT information: Failed to assign to property 'HexEditor.Controls.NavButton.Command'. [Line: 29 Position: 41] 
Additional information: The text associated with this error code could not be found. 

Failed to assign to property 'HexEditor.Controls.NavButton.Command'. [Line: 29 Position: 41] 

私は間違っていますか?

+0

[DependencyProperty.Register'の3番目のパラメータ](https://msdn.microsoft.com/library/windows/apps/hh701829)は、所有するクラスのタイプです。あなたのケースでは、すべての依存関係プロパティのための 'typeof(NavButton)'です。また、 'bool'型の依存性プロパティーと' ICommand'(両方のケースでは 'new PropertyMetadata(" ")')のデフォルト値は '' ''です。いずれかの文字列にキャストすることはできません。 'IsChecked'はデフォルトで' false'に、 'Command'はデフォルトで' null'に設定されます。 –

+0

@ed、例外はなくなりました、ありがとうございます。 –

答えて

0

私は、タイプboolICommand(どちらの場合もnew PropertyMetadata(""))の依存関係プロパティのデフォルト値が ""だと思います。文字列をどちらかにキャストすることはできません。そうすれば、例外がスローされます。 IsCheckedは、デフォルトでfalseになり、Commandはデフォルトでnullになります。

これは、あなたが尋ねている正確な問題と関連しているかもしれませんが、重要でもあります。DependencyProperty.Register()の3番目のパラメータは、所有するクラスのタイプである必要があります。あなたのケースでは、それはすべての依存関係プロパティのためにtypeof(NavButton)です。