错误绑定用户控件wp7的属性

时间:2012-02-29 15:37:37

标签: wpf windows-phone-7 xaml binding user-controls

我创建了一个用户控件,在app周围的多个地方使用它,控件有两个属性,女巫值被绑定到viewmodel。问题是,当应用程序加载它时,在设置用户控件的一个属性时抛出异常,任何想法?

用户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}"/>

ViewModel属性片段与UserControl.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)

我发现异常的来源是MainPage上的绑定,但并不真正理解为什么或导致它的原因。

由于

2 个答案:

答案 0 :(得分:1)

您通过在usercontrol中明确设置DataContext而丢失了DependencyProperty。此外,您应该使用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; } } } 。最后,您的XAML加载了Exact边距...您可能希望切换到使用网格行/列定义,就好像您需要更改页面一样,它会更容易。

<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>

{{1}}

答案 1 :(得分:0)

我不确定,但构造函数中的代码块是什么:

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

看起来很“危险”......