[英]XAML binding from a string to TextBox not working
我是一名C#新手,他在理解為什么他第一次嘗試理解XAML綁定不起作用時遇到了問題。 我正在關注Microsoft的數據綁定概述 。
我只有一個TextBox,它將最終用作狀態窗口。 現在,我只想能夠在其中寫入任意文本字符串。 我也有一個正在測試的命令模式的實例。 我的命令涉及將一個隨機數添加到累加器,然后將結果打印到狀態視圖。
這是主應用程序窗口的XAML:
<Window x:Class="Experiment.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Experiment"
Title="Test" Height="500" Width="700" Name="Test" Closing="Test_Closing" DataContext="{Binding ElementName=statusText}" xmlns:my="clr-namespace:Experiment">
<Window.Resources>
<c:StatusViewText x:Key="statusViewText" />
</Window.Resources>
<DockPanel HorizontalAlignment="Stretch" Margin="0,0,0,0" Width="Auto">
<!-- Elements deleted for brevity. -->
<TextBox Margin="5,5,5,5" Name="statusText" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" FontFamily="Courier New" FontSize="12"
Text="{Binding Source={StaticResource statusViewText}, Path=statusTextString, Mode=OneWay}"/>
</DockPanel>
</Window>
和代表我的數據的類:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Experiment {
public class StatusViewText {
public StringBuilder statusText { get; set; }
public String statusTextString { get; set; }
public StatusViewText() {
statusText = new StringBuilder();
}
public void Append(string s) {
if (s != null) {
statusText.Append(s);
}
statusTextString = statusText.ToString();
}
public void AppendLine(string s) {
if (s != null) {
statusText.AppendLine(s);
}
statusTextString = statusText.ToString();
}
}
}
最終,我將在這里使用StringBuilder的適當轉換器,但是在探索這種復雜性之前,我想先了解一下原理。
如果我的理解是正確的(顯然不是),那么所有這些都應該起作用。 綁定目標是TextBox,目標屬性是Text屬性。 綁定源是StatusViewText類的statusTextString屬性。 但是,當我運行命令(並調試並查看StatusViewText.statusTextString正在更新)時,TextBox不會更新。
我以為自己可能需要顯式添加綁定,因此我嘗試在主窗口構造函數的InitializeComponent()
之后添加此綁定:
statusViewText = new StatusViewText();
Binding statusViewTextBinding = new Binding("statusTextString");
statusViewTextBinding.Source = statusViewText;
statusText.SetBinding(TextBlock.TextProperty, statusViewTextBinding);
但這也不起作用。
我是否需要觸發PropertyChanged事件? 我認為綁定框架的全部目的是自動觸發事件並在幕后消耗事件; 但也許我也是錯的。
在“輸出”窗口中沒有出現明顯的錯誤,這使我相信我的綁定語法是正確的。 我只是想念其他東西。
!
編輯13:14 EDT謝謝mben :
好吧,我做到了。 添加了以下內容:
public class StatusViewText : INotifyPropertyChanged {
public void Append(string s) {
if (s != null) {
statusText.Append(s);
}
statusTextString = statusText.ToString();
NotifyPropertyChanged("statusTextString");
}
public void AppendLine(string s) {
if (s != null) {
statusText.AppendLine(s);
}
statusTextString = statusText.ToString();
NotifyPropertyChanged("statusTextString");
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
我調試以驗證它是否正在通過此代碼路徑。 但是仍然沒有運氣。 還有其他想法嗎?
這是您需要應用使其生效的更改。
這是您的ViewModel的代碼:
public class StatusViewText : INotifyPropertyChanged
{
public StatusViewText()
{
// At least, I have a default value
this.StatusTextString = "Hello world";
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string statusTextString;
public string StatusTextString
{
get { return this.statusTextString; }
set
{
this.statusTextString = value;
this.OnPropertyChanged("StatusTextString");
}
}
}
您必須指定窗口的DataContext。 后面的代碼是一個解決方案:在MainWindow的ctor中,填充數據上下文:
this.DataContext = new StatusViewText();
在XAML中,您應該說對屬性StatusTextString的綁定。 之所以有效,是因為數據上下文是StatusViewText的實例。
Text="{Binding Path=StatusTextString}"
您仍然需要在StatusViewText上實現INotifyPropertyChanged。 綁定系統不會連續檢查這些值,您需要在情況發生變化時通知它。
請注意,您正在代碼中創建一個實例,該實例與Xaml中表示的實例不同。 您可以通過在StatusViewText的構造函數中設置一個斷點來證明這一點。
將此片段放入MainWindow的構造函數中...
StatusViewText o = (StatusViewText)FindResource("statusViewText") as StatusViewText;
if(o!=null)
{
o.Append("hello");
}
這將影響您的類的正確實例。
您還應該更改班級,使其看起來像這樣……
public class StatusViewText:INotifyPropertyChanged
{
public StringBuilder statusText { get; set; }
private string _statusTextString;
public String statusTextString
{
get { return _statusTextString; }
set
{
_statusTextString = value;
OnPropertyChanged("statusTextString");
}
}
public StatusViewText()
{
statusText = new StringBuilder();
}
public void Append(string s)
{
if (s != null)
{
statusText.Append(s);
}
statusTextString = statusText.ToString();
}
public void AppendLine(string s)
{
if (s != null)
{
statusText.AppendLine(s);
}
statusTextString = statusText.ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string prop)
{
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.