开发者

Dynamically created Binding does not work

开发者 https://www.devze.com 2023-04-09 08:09 出处:网络
I want to bind TextBlocks to a Modell. But it does not work and I have no idea why. class GameModel : INotifyPropertyChanged {

I want to bind TextBlocks to a Modell. But it does not work and I have no idea why.

class GameModel : INotifyPropertyChanged {
string[] _teamNames;
 ...
public string teamName(int team)
{
  return _teamNames[team];
}

public void setTeamName(int team, string name)
{
  _teamNames[team] = name;
  OnPropertyChanged("teamName");
}

protected void OnPropertyChanged(string name) {
 PropertyChangedEventHandler handler = PropertyChanged;
 if (handler != null)
  {
     handler(开发者_高级运维this, new PropertyChangedEventArgs(name));
  }
}

And the code which creates the TextBoxes

for (int currCol = 0; currCol < teams; currCol++) {
  TextBlock teamNameBlock = new TextBlock();
  Binding myNameBinding = new Binding();
  myNameBinding.Source = myGame;
  myNameBinding.Path = new PropertyPath("teamName", currCol);
  myNameBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
  teamNameBlock.SetBinding(TextBlock.TextProperty, myNameBinding); //The name of the team bind to the TextBlock
...
}


Here's a full, working example. The idea is to use an indexed property to access the team names. Note how the binding path is created: PropertyPath("[" + currCol + "]") , and how the property change is notified: OnPropertyChanged("Item[]"); After the creation of controls, the name of the 3rd team is changed to "Marge" to test the binding.

using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;

namespace TestBinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();      
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            CreateTeamControls();
            myGame[2] = "Marge";
        }

        void CreateTeamControls()
        {
            var panel = new StackPanel();
            this.Content = panel;
            int teams = myGame.TeamCount;

            for (int currCol = 0; currCol < teams; currCol++)
            {
                TextBlock teamNameBlock = new TextBlock();

                panel.Children.Add(teamNameBlock);

                Binding myNameBinding = new Binding();
                myNameBinding.Source = myGame;
                myNameBinding.Path = new PropertyPath("[" + currCol + "]");
                myNameBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                teamNameBlock.SetBinding(TextBlock.TextProperty, myNameBinding);
            }
        }

        GameModel myGame = new GameModel();
    }
}

class GameModel : INotifyPropertyChanged 
{
    string[] _teamNames = new string[3];

    public int TeamCount { get { return _teamNames.Count(); } }

    public GameModel()
    {
        _teamNames[0] = "Bart";
        _teamNames[1] = "Lisa";
        _teamNames[2] = "Homer";
    }

    public string this[int TeamName]
    {
        get
        {
            return _teamNames[TeamName];
        }
        set
        {
            if (_teamNames[TeamName] != value)
            {
                _teamNames[TeamName] = value;
                OnPropertyChanged("Item[]");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        var changedHandler = this.PropertyChanged;
        if (changedHandler != null)
            changedHandler(this, new PropertyChangedEventArgs(propertyName));
    }
}


I think the problem is you bind to

public string teamName(int team)
{
  return _teamNames[team];
}

what is team parameter and the moment of change? Who sets that parameter. Make something like this, instead:

    public string teamName
    {
      get 
      {
            return _teamNames[currTeam];
      }
    }

You bind to a property, which returns the team name based on currTeam index, which is settuped based on you app logic.

Hope this helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号