guo
guo

Reputation: 10219

WPF: Why can't I bind data?

<Window x:Class="GuessFigure.PlayingGameWindow"
        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:local="clr-namespace:GuessFigure"
        mc:Ignorable="d"
        Title="PlayingGame" Height="300" Width="300">
    <Grid
        xmlns:c="clr-namespace:GuessFigure.Model">
        <Grid.Resources>
            <c:Round x:Key="round"/>
        </Grid.Resources>
        <Grid.DataContext>
            <Binding Source=" {StaticResource round}" />
        </Grid.DataContext>
        <TextBlock x:Name="tbTime" HorizontalAlignment="Left" Margin="108,202,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="123,86,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
        <TextBlock x:Name="roundNumber" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="{Binding Path=Number}"/>

    </Grid>
</Window>

Round.cs:

using GuessFigure.Model.Factory;
using Ninject;
using Ninject.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject.Planning.Bindings;

namespace GuessFigure.Model
{
    /// <summary>
    /// 回合
    /// 
    /// 每回合限时30s,超时直接进入下一回合
    /// 
    /// 题目(数字)由FigureFactory类生产
    /// </summary>
    /// 
    class Round
    {
        /// <summary>
        /// 回合数 
        /// 
        /// 一共五回合,每回合出一道猜数字的题目
        /// </summary>
        internal int Number { get; } = 1;

        /// <summary>
        /// 生产题目的工厂
        /// </summary>
        private FigureFactory figureFactory;

       [Inject]
       internal void  SetFigureFactory(FigureFactory figureFactory)
        {
            this.figureFactory = figureFactory;
        }

        /// <summary>
        /// 调用<see cref=">FigureFactory"/>
        /// </summary>
        /// <returns>
        /// 当前回合的题目。
        /// </returns>
        public int[] GetCurrentRoundFigures()
        {
            return figureFactory.Produce(Number);
        }
    }



    class RoundModule : NinjectModule
    {
        public override void Load()
        {
            Bind<FigureFactory>().To<FigureFactoryRound1>().When(request=>request.ParentRequest.Target.Type.GetField("number").Equals(1));
            Bind<FigureFactory>().To<FigureFactoryRound2>().When(request => request.Target.Type.GetField("number").Equals(2));
            Bind<FigureFactory>().To<FigureFactoryRound3>().When(request => request.Target.Type.GetField("number").Equals(3));
            Bind<FigureFactory>().To<FigureFactoryRound4>().When(request => request.Target.Type.GetField("number").Equals(4));
            Bind<FigureFactory>().To<FigureFactoryRound5>().When(request => request.Target.Type.GetField("number").Equals(5));

        }
    }


}

I want to bind class Round's property Number to the second TextBlock in Grid and show it to user. However, there was nothing show after I made these code.

What's wrong in my code?

System.Windows.Data Error: 40 : BindingExpression path error: 'Number' property not found on 'object' ''String' (HashCode=-1455514144)'. BindingExpression:Path=Number; DataItem='String' (HashCode=-1455514144); target element is 'TextBlock' (Name='roundNumber'); target property is 'Text' (type 'String')

Related question may help: WPF/XAML Property not found on 'object'

Upvotes: 0

Views: 456

Answers (3)

Red Wei
Red Wei

Reputation: 940

  • Your are trying to bind an attribute to a internal property which is wrong. The attribute can only bind to an public property.
  • Public property is recommend to capitalize first letter.

Upvotes: 0

guo
guo

Reputation: 10219

First of all, my code has multiple wrongs, and thank Maarten who indicated that

The property you bind to has to be public, your property is internal.

However that was not enough and the problem was still there. I solved my problem at last, by remove the blank space before {StaticResource round} in <Binding Source=" {StaticResource round}" />.

Now the binding runs as I expect.

Upvotes: 0

Maarten
Maarten

Reputation: 22945

The property you bind to has to be public, your property is internal. See here.

The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.

Also, this:

request.Target.Type.GetField("number").Equals(2)

Will not work since:

  • Number has a capital N
  • is a property
  • GetField("Number") returns aFieldInfo` instance, not the value.

So what you can try is this:

request.Target.Type.GetProperty("number").GetValue(request.Target, null).Equals(2)

Upvotes: 1

Related Questions