2012-02-29 7 views
0

私は、アプリケーションの周りの複数の場所でそれを使用するユーザーコントロールを作成しました。コントロールには2つのプロパティがあり、witchの値はビューモデルにバインドされます。問題は、アプリがそれをロードしているときに、ユーザーコントロールのプロパティのいずれかを設定している間に例外をスローするというものです。エラーユーザーコントロールのプロパティをバインドする

ユーザControl.xaml

<UserControl x:Class="Client.Controls.CredentialsUserControl" 
    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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    d:DesignHeight="480" d:DesignWidth="480"> 

    <Grid Name="LayoutRoot"> 

     <TextBlock Text="{Binding Title}" Margin="12,20,12,390" TextWrapping="Wrap" FontSize="30"/> 

     <TextBlock Text="Username" Margin="39,88,260,362" FontSize="25"/> 
     <TextBlock Text="{Binding Credentials.User}" Margin="361,88,0,362" FontSize="25" /> 

     <TextBlock Text="Password" Margin="39,148,260,302" FontSize="25"/> 
     <TextBlock Text="{Binding Credentials.Password}" Margin="361,148,0,302" FontSize="25" /> 

</UserControl> 

UserControl.xaml.cs

public partial class CredentialUserControl: UserControl , INotifyPropertyChanged 
{ 

    public const string CredentialsPropertyName = "Credentials"; 

    private ICredentials _credentials= null; 
    public ICredentials Credentials 
    { 
     get 
     { 
      _credentials_report; 
     } 

     set 
     { 
      if (_credentials== value) 
      { 
       return; 
      } 

      _credentials= value; 
      NotifyPropertyChanged(CredentialsPropertyName); 
     } 
    } 

    public string Title { get; set; } 



    public MobfoxReportUserControl() 
    { 
     InitializeComponent(); 

     Loaded += PageLoaded; 
    } 

    void PageLoaded(object sender, RoutedEventArgs e) 
    { 
     this.DataContext = this; 

    } 


    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(string prop) 
    { 
     if(PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
    } 
} 

使用:

<Controls:CredentialsUserControl Title="Your Credentials" Credentials="{Binding CurrentUser}"/> 

ビューモデルプロパティスニペットは、ユーザーコントロールに示したと同じです.xaml.cs

System.Windows.Markup.XamlParseException occurred 
    Message=Set property 'CredentialsUserControl.Credentials' threw an exception. [Line: 29 Position: 85] 
    InnerException: System.ArgumentException 
     Message=ArgumentException 
     StackTrace: 
      at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark) 
      at System.Reflection.RuntimePropertyInfo.InternalSetValue(PropertyInfo thisProperty, Object obj, Object value, Object[] index, StackCrawlMark& stackMark) 
      at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index) 

を投げられる

例外は私が見つけたとすると、例外の起源は、メインページ上で結合されていることですが、本当に理由を理解していないか、またはそれを引き起こしているもの。

おかげ

+1

'this.DataContext =この;'それは何ですか?コンストラクタ – Ku6opr

+0

@ Ku6oprから 'LayoutRoot.DataContext = this;'と 'this.DataContext = this;'を削除してください。確かに "間違った"臭い – Stuart

+0

コードを編集しますが、問題はまだ同じですXD – DVD

答えて

1

あなたが失っていますDataContextを明示的にusercontrol内に設定します。さらに、DependencyPropertyを使用する必要があります。最後に、XAMLに正確な余白が読み込まれます。グリッド行/列定義を使用するように切り替えることができます。あたかもページを変更する必要があるかのように、簡単になります。

using System.Net; 
using System.Windows; 
using System.Windows.Controls; 

namespace Client.Controls 
{ 
    public partial class CredentialsUserControl : UserControl 
    { 
     public CredentialsUserControl() 
     { 
      InitializeComponent(); 

      if (System.ComponentModel.DesignerProperties.IsInDesignTool) 
      { 
       Credentials = new NetworkCredential("user","pass"); 
       Title = "testing creds"; 
      } 
     } 



     public ICredentials Credentials 
     { 
      get { return (ICredentials)GetValue(CredentialsProperty); } 
      set { SetValue(CredentialsProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for Credentials. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty CredentialsProperty = 
      DependencyProperty.Register("Credentials", typeof(ICredentials), typeof(CredentialsUserControl),new PropertyMetadata(null)); 

     public string Title { get; set; } 

    } 
} 

<Grid Name="LayoutRoot"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 

    <TextBlock Text="{Binding ElementName=control, Path=Title}" TextWrapping="Wrap" FontSize="30" Margin="12,24" /> 

    <Grid Grid.Row="1" Margin="40,0,0,0"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="12" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <TextBlock Text="Username" FontSize="25" Grid.Column="0" /> 
     <TextBlock Text="{Binding ElementName=control, Path=Credentials.User}" FontSize="25" Grid.Column="1" HorizontalAlignment="Right"/> 

     <TextBlock Text="Password" Grid.Row="2" FontSize="25" Grid.Column="0" /> 
     <TextBlock Text="{Binding ElementName=control, Path=Credentials.Password}" Grid.Row="2" FontSize="25" Grid.Column="1" HorizontalAlignment="Right"/> 
    </Grid> 
</Grid> 

+0

私はすでにそれに気付きました。 Btwあなたのグリッドの提案は最高だったxDD – DVD

0

私はわからないんだけど、このコードブロックは、あなたのコンストラクタで何です:

LayoutRoot.DataContext = this; 
    this.DataContext = this; 

それは「危ない」に見える...

+0

問題ではなく、私の元のコードが更新されました。この問題は、ロードされたイベントでコンテキストが設定されている場合でも維持されます。 – DVD

+0

ViewModel/Dataコンテキストが実際にCurrentUserのICredentialsを提供しているとしますか? – Stuart

+0

はい、私はusercontrol xamlコードをメインページに入れても問題ありません。 – DVD

関連する問題