2016-10-11 3 views
1

У меня проблема с привязкой DependencyProperty типа ICommand. Это мой пользовательский элемент управления пользователя:UWP ICommand DependencyProperty cast error

<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'] (https://msdn.microsoft.com/library/windows/apps/hh701829) является типом владеющего класса. Это 'typeof (NavButton)' в вашем случае, для всех его свойств зависимостей. Кроме того, у вас есть значения по умолчанию '' '' для свойств зависимостей типа 'bool' и' ICommand' ('new PropertyMetadata (" ")' в обоих случаях). Вы не можете передать строку ни одному из них. 'IsChecked' должен по умолчанию« false », а' Command' должен по умолчанию «null». –

+0

@ed, исключение прошло, спасибо. –

ответ

0

Я думаю, проблема в том, что у вас есть значения по умолчанию для свойств зависимостей типа bool и ICommand (new PropertyMetadata("") в обоих случаях). Вы не можете передать строку ни одному, и это вызовет исключение. IsChecked должен по умолчанию false, а Command должен по умолчанию null.

Это может быть или не быть актуальным для конкретной проблемы, о которой вы просите, но это также имеет значение. Третий параметр DependencyProperty.Register() должен быть типом владеющего класса. Это typeof(NavButton) в вашем случае, для всех его свойств зависимостей.

 Смежные вопросы

  • Нет связанных вопросов^_^