Ошибка привязки свойства пользовательского элемента управления wp7 - PullRequest
0 голосов
/ 29 февраля 2012

Я создал пользовательский элемент управления, чтобы использовать его в нескольких местах вокруг приложения, элемент управления имеет два свойства, значение ведьмы привязано к модели представления. проблема в том, что когда приложение загружается, оно выдает исключение при установке одного из свойств пользовательского элемента управления, любая идея?

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

Что я обнаружил, так это то, что источником исключения является привязка на главной странице, но на самом деле он не понимал, почему или что его вызывает.

Спасибо

Ответы [ 2 ]

1 голос
/ 01 марта 2012

Вы теряете DataContext, явно устанавливая его в своем пользовательском контроле. Кроме того, вы должны использовать 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 голосов
/ 29 февраля 2012

Я не уверен, но что это за блок кода в вашем конструкторе:

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

Это выглядит "опасно" ...

...