动态创建的Binding不起作用

发布于 2024-12-07 13:24:55 字数 985 浏览 0 评论 0原文

我想将 TextBlock 绑定到 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
...
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

将军与妓 2024-12-14 13:24:55

这是一个完整的、有效的示例。这个想法是使用索引属性来访问团队名称。
请注意如何创建绑定路径:PropertyPath("[" + currCol + "]") ,以及如何通知属性更改:OnPropertyChanged("Item[]");
创建控件后,将第三组的名称更改为“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));
    }
}

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));
    }
}
我还不会笑 2024-12-14 13:24:55

我认为问题是您绑定到

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

什么是“team”参数以及更改的时刻?谁设置该参数。
相反,请进行如下操作:

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

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

希望这有帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文