【问题标题】:Dynamically created Binding does not work动态创建的绑定不起作用
【发布时间】:2011-11-28 12:13:15
【问题描述】:

我想将 TextBlocks 绑定到 Modell。但它不起作用,我不知道为什么。

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));
  }
}

以及创建文本框的代码

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

【问题讨论】:

  • 这可能不是唯一的问题,但您的 teamName 函数不是属性。您应该查看有关“索引属性”的文档
  • 有没有可能绑定一个函数结果?
  • 不,你必须绑定到一个属性,但你可以在属性的“get{}”中调用一个函数
  • 实际上可以使用转换器绑定到方法。示例见stackoverflow.com/questions/502250/bind-to-a-method-in-wpf

标签: c# .net wpf binding


【解决方案1】:

这是一个完整的工作示例。这个想法是使用索引属性来访问团队名称。 注意绑定路径是如何创建的: PropertyPath("[" + currCol + "]") ,以及如何通知属性更改: OnPropertyChanged("Item[]"); 创建控件后,将第 3 组的名称更改为“Marge”以测试绑定。

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));
    }
}

【讨论】:

    【解决方案2】:

    我认为问题是你绑定到

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

    什么是team参数和变化的时刻?谁设置该参数。 改成这样:

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

    您绑定到一个属性,该属性根据currTeam 索引返回团队名称,该索引是根据您的应用逻辑设置的。

    希望这会有所帮助。

    【讨论】:

    • 谢谢,但我无法返回数组。有多个团队名称。我可以通过其他方式传递 currTeam-Parameter 吗?
    • 好的,我试过了。 Modell 返回一个字符串数组,PropertyPath 是 'PropertyPath("teamName[" + currCol + "]")' 但仍然没有效果。
    • 您仍在尝试绑定到某个字段。看到这个帖子:stackoverflow.com/questions/1481130/…
    • @Tobi:查看提供的代码,我认为不需要返回字符串数组。再次根据提供的代码,您想要的是在文本框中显示当前 TeamName。只需像我的答案一样绑定它的 teamname 属性,除此之外,将 currTeam 索引更改为在可用的不同团队名称之间切换。
    • 嗯,团队的数量是动态的。所以我必须将数组内的值绑定到控件。 currTeam 是从 elemen-bind-path 设置的
    猜你喜欢
    • 2017-04-19
    • 2015-06-26
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2012-09-17
    • 1970-01-01
    相关资源
    最近更新 更多