WPF TextBlock绑定到一个字符串

4
我可以帮您进行翻译。需要翻译的内容是关于IT技术的,您希望将一个文本块(TextBlock)绑定到一个从txt文件中获取值的字符串上。该字符串已经被正确填充,但其内容未显示。
类文件如下:
public partial class JokesMessageBox : Window
    {
        public JokesMessageBox()
        {
            InitializeComponent();
        }

        public string Joke { get; set; }
        public string path = "data/jokes.txt";

        public void ReadFile(string path)
        {
            Joke = File.ReadAllText(path);
        }
    }

XAML:

<TextBlock HorizontalAlignment="Left" Margin="22,10,0,0"
 TextWrapping="Wrap" Text="{Binding Joke}" VerticalAlignment="Top"
 Height="60" Width="309"/>

编辑:

在MainWindow类中:

 private void btnJokesFirstScreen_Click_1(object sender, RoutedEventArgs e)
        {
  JokesMessageBox jkb = new JokesMessageBox();
                jkb.Show();
                jkb.ReadFile("data/jokes.txt");
        }

我在谷歌、油管、MSDN和StackOverflow上花了三个多小时,但仍然无法让它正常工作。我错过了什么吗?


1
ReadFile 函数是如何/何时被调用的? - O. R. Mapper
在构造函数中调用readfile。 - Kevin Avignon
我建议你阅读一些关于"数据绑定(DataBinding)"的内容。 - dbvega
我加上了调用ReadFile()的位置。 - Bruno
3个回答

10

如果您需要更新绑定,属性Joke必须是一个DependencyProperty或者Windows必须实现INotifyPropertyChanged接口。

在视图上,绑定需要知道Source

示例1(使用DependencyProperty):

public partial class JokesMessageBox : Window
{
    public JokesMessageBox()
    {
        InitializeComponent();

        ReadFile(Path); //example call
    }

    public string Joke
    {
        get { return (string)GetValue(JokeProperty); }
        set { SetValue(JokeProperty, value); }
    }

    public static readonly DependencyProperty JokeProperty =
        DependencyProperty.Register("Joke", typeof(string), typeof(JokesMessageBox), new PropertyMetadata(null));


    public const string Path = "data/jokes.txt";

    public void ReadFile(string path)
    {
        Joke = File.ReadAllText(path);
    }
}

示例 #2(使用 INotifyPropertyChanged 接口):

public partial class JokesMessageBox : Window, INotifyPropertyChanged
{
    public JokesMessageBox()
    {
        InitializeComponent();

        ReadFile(Path); //example call
    }

    private string _joke;

    public string Joke
    {
        get { return _joke; }
        set
        {
            if (string.Equals(value, _joke))
                return;
            _joke = value;
            OnPropertyChanged("Joke");
        }
    }

    public const string Path = "data/jokes.txt";

    public void ReadFile(string path)
    {
        Joke = File.ReadAllText(path);
    }


    //INotifyPropertyChanged members
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

视图(XAML部分):

...
<TextBlock HorizontalAlignment="Left" Margin="22,10,0,0"
    TextWrapping="Wrap" 
    Text="{Binding Joke,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}" 
    VerticalAlignment="Top"
    Height="60" Width="309"/>
...

我希望这能有所帮助。


这个方法可行!我选择了第二个例子。在阅读了这篇文章之后:链接,我认为这是一个快速而简单的解决方案。现在我看到其他人发布的类似问题,我注意到了INotifyPropertyChanged接口。我会进一步研究它。谢谢! - Bruno

0
当你读取文件内容时,将读取的字符串赋值给你的Joke属性。
Joke = File.ReadAllText(path);

TextBlockText property确实绑定到该属性上(如果你已经正确设置了data context):

Text="{Binding Joke}"

然而,缺少的是绑定无法知道属性值已更改。您需要发出有关属性更改的通知

有两种方法可以做到这一点,WPF绑定将识别:

  • 将您的Joke属性声明为依赖属性。这基于一些WPF基础设施,自动发出更改通知。
  • 使您的类实现INotifyPropertyChanged接口。在这里,您必须实现一个简单的接口,其中包含一个PropertyChanged事件,您必须在属性设置器中触发该事件,并传递属性名称作为字符串。

0
你的类没有实现INotifyPropertyChanged接口。因此,当你更改属性Joke TextBlock时,它不会被更新。我会这样做:
public partial class JokesMessageBox : Window, INotifyPropertyChanged
    {
        public JokesMessageBox()
        {
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public string Joke { get; set; }
        public string path = "data/jokes.txt";

        public void ReadFile(string path)
        {
            Joke = File.ReadAllText(path);
            OnPropertyChanged("Joke");
        }

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

我还建议你阅读关于MVVM模式的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接