Связывание данных с набором инструментов MVVM Light - PullRequest
0 голосов
/ 02 декабря 2011

У меня возникли проблемы с привязкой с использованием инструментария MVVM, и я хотел бы дать несколько советов, если я все сделаю правильно.Во-первых, у меня есть локатор модели представления, который определяется следующим образом:

public class ViewModelLocator
{
    private static MainViewModel _main;
    private static ProductViewModel _product;

    /// <summary>
    /// Initializes a new instance of the ViewModelLocator class.
    /// </summary>
    public ViewModelLocator()
    {
        ////if (ViewModelBase.IsInDesignModeStatic)
        ////{
        ////    // Create design time view models
        ////}
        ////else
        ////{
        ////    // Create run time view models
        ////}

        CreateMain();
        CreateProduct();
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    public static MainViewModel MainStatic
    {
        get
        {
            if (_main == null)
            {
                CreateMain();
            }

            return _main;
        }
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    public static ProductViewModel ProductStatic
    {
        get
        {
            if (_product == null)
            {
                CreateProduct();
            }

            return _product;
        }
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return MainStatic;
        }
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public ProductViewModel Product
    {
        get
        {
            return ProductStatic;
        }
    }

    /// <summary>
    /// Provides a deterministic way to delete the Main property.
    /// </summary>
    public static void ClearMain()
    {
        _main.Cleanup();
        _main = null;
    }

    /// <summary>
    /// Provides a deterministic way to create the Main property.
    /// </summary>
    public static void CreateMain()
    {
        if (_main == null)
        {
            _main = new MainViewModel();
        }
    }

    /// <summary>
    /// Provides a deterministic way to create the Main property.
    /// </summary>
    public static void CreateProduct()
    {
        if (_product == null)
        {
            _product = new ProductViewModel();
        }
    }

    /// <summary>
    /// Cleans up all the resources.
    /// </summary>
    public static void Cleanup()
    {
        ClearMain();
    }
}

Затем у меня есть главное окно, для которого я установил текст данных: DataContext = "{Binding Source = {x: Static vm: ViewModelLocator.MainStatic}} "

Внутри моего главного окна у меня есть список, в котором в качестве ItemSource будет содержаться коллекция ProductViewModel , определяемая следующим образом:

 public class ProductViewModel : ViewModelBase
{

     SvcProduct.ProductServiceClient _clientSvc =new SvcProduct.ProductServiceClient() ;
     ObservableCollection<Product> _products = new ObservableCollection<Product>();


     public ObservableCollection<Product> Products
     {
         get { return _products; }
         set { _products = value; }
     }

    /// <summary>
    /// Initializes a new instance of the ProductViewModel class.
    /// </summary>
    public ProductViewModel()
    {
        ////if (IsInDesignMode)
        ////{
        ////    // Code runs in Blend --> create design time data.
        ////}
        ////else
        ////{
        ////    // Code runs "for real": Connect to service, etc...
        ////}
        _products=_clientSvc.GetProducts();

    }

    ////public override void Cleanup()
    ////{
    ////    // Clean own resources if needed

    ////    base.Cleanup();
    ////}
}

ProductViewModel возвращает в Products коллекцию для списка.Каждый элемент в списке подключен к ProductView, который представляет собой userControl, определяемый следующим образом:

<UserControl
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"
xmlns:vm="clr-namespace:Solatys.Presentation.ViewModel"
mc:Ignorable="d"
x:Class="Solatys.Presentation.ProductView"
x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480" Width="433" Height="319"
IsManipulationEnabled="True"
DataContext="{Binding Source={x:Static vm:ViewModelLocator.ProductStatic}}">

<Grid x:Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="144.3"/>
        <ColumnDefinition Width="0.64*"/>
        <ColumnDefinition Width="144.3"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="35" MaxHeight="35"/>
        <RowDefinition Height="130" MaxHeight="130"/>
        <RowDefinition Height="130" MaxHeight="130"/>
        <RowDefinition Height="24" MaxHeight="24"/>
    </Grid.RowDefinitions>
        <Image Source="Resources/beauté.jpg" Grid.Row="1" Stretch="UniformToFill" Grid.RowSpan="2" Grid.ColumnSpan="3"/>
    <TextBlock TextWrapping="Wrap" Grid.Column="1" Text="{Binding ProductName}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16" Foreground="White" FontFamily="Perpetua Titling MT" TextAlignment="Justify"/>
        <Border BorderBrush="Black" BorderThickness="0" Grid.Row="3" Grid.ColumnSpan="3">
            <Border.Background>
                <RadialGradientBrush>
                    <GradientStop Color="#00000000" Offset="1"/>
                    <GradientStop Color="#FF005E01"/>
                </RadialGradientBrush>
            </Border.Background>
            <TextBlock TextWrapping="Wrap" Text="Coup de Coeur" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Perpetua" TextAlignment="Justify" FontSize="13.333"/>
        </Border>

        <Border Grid.Row="1" Grid.Column="0" Background="#7F000000" d:LayoutOverrides="Width">
            <TextBlock TextWrapping="Wrap"  Foreground="White" FontFamily="Perpetua" Margin="5"><Run Text="Type de produit"/><Run Language="fr-fr" Text=" : "/><LineBreak/><Run Language="fr-fr"/><LineBreak/><Run Language="fr-fr" Text="Produit de beauté Bio"/></TextBlock>
        </Border>

        <Border HorizontalAlignment="Right" Grid.Row="1" Grid.Column="2" Width="144.3" Height="130" Background="#7F000000">
            <TextBlock Margin="5" TextWrapping="Wrap" Foreground="White" FontFamily="Perpetua"><Run Text="Court descriptif"/><LineBreak/><Run/><LineBreak/><Run Language="fr-fr" Text="Ce nouveau produit reste notre coup de coeur pour ses propriétés naturelles ..."/></TextBlock>
        </Border>

        <Border HorizontalAlignment="Center" Grid.Row="2" Grid.Column="1" Width="144.3" Height="130" Background="#7F000000">
            <TextBlock TextWrapping="Wrap" Margin="5" Foreground="White" FontFamily="Perpetua"><Run Text="Caractéristiques du produit"/><Run Language="fr-fr" Text=" : "/><LineBreak/><Run Language="fr-fr"/><LineBreak/><Run Language="fr-fr" Text="- rajeunissant"/><LineBreak/><Run Language="fr-fr" Text="- vivifiant"/><LineBreak/><Run Language="fr-fr" Text="- prix attractif"/><LineBreak/><Run Language="fr-fr" Text="- produit contrôlé"/></TextBlock>
        </Border>

</Grid>

Как вы можете видеть выше, DataContext установлен в ViewModelLocator.ProductStatic, но онговорит об ошибке типа «Невозможно создать экземпляр ViewModelLocator»

Из-за этого кажется, что привязка не работает, так как мой список пуст в главном окне

1 - Любая идея, что ясделать неправильно для этой ошибки?2- Как мне связать ItemSource с моим сценарием, поскольку коллекция является коллекцией ProductViewModel?

С уважением, serge

1 Ответ

1 голос
/ 02 декабря 2011

«Невозможно создать экземпляр ViewModelLocator» обычно является признаком того, что что-то пошло не так во время создания виртуальных машин. Попробуйте установить точку останова на _products = _clientSvc.GetProducts (), а затем отладить код. Я почти уверен, что в этом методе что-то идет не так, и выдается исключение, которое также приводит к сбою ViewModelLocator.

Ура, Laurent

...