绑定变量未使用INotifyPropertyChanged更新并设置DataContext

时间:2018-02-19 11:13:14

标签: c# wpf xaml mvvm data-binding

我正在编写一个简单的宏程序,你可以创建宏,并通过这样做我想创建一个用户控件,它将是一个新的宏编辑器。每个宏编辑器都有两个文本框。左边是您需要按下的按键,右侧文本框显示按下第一个按键后输出的按键。我使用绑定这两个文本框但似乎没有更新。它只显示起始值。

C#:

public MacroControl()
{
    InitializeComponent();
    DataContext = this;
    Thread checkKeys = new Thread(new ThreadStart(CheckKeys));
    checkKeys.Start();
}

private string[] _text = {null,null};
public string[] Text
{
    get { return _text; }
    set
    {
        if(_text != value)
        {
            _text = value;
            NotifyPropertyChanged();
        }
    }
}


    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBoxIndex = 0;
        Text[TextBoxIndex] = "test";
    }

    private void TextBox_GotFocus_1(object sender, RoutedEventArgs e)
    {
        TextBoxIndex = 1;
        Text[TextBoxIndex] = "test";
    }

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="250*"/>
    <ColumnDefinition Width="141*"/>
    <ColumnDefinition Width="109*"/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="20" HorizontalAlignment="Center" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="236,12,126.625,11">⟶</TextBlock>
<TextBox IsReadOnly="True" Text="{Binding Text[0]}" GotFocus="TextBox_GotFocus" Background="Transparent" Margin="15"  Grid.Column="0"/>
<TextBox IsReadOnly="True" Text="{Binding Text[1]}" GotFocus="TextBox_GotFocus_1" Background="Transparent" Margin="15"  Grid.Column="1" Grid.ColumnSpan="2"/>

2 个答案:

答案 0 :(得分:1)

正如我在评论中提到的,数组不会触发PropertyChanged个事件,因此你的Binding甚至不知道你改变了价值。一个潜在的解决方法是在更改项目后手动调用它:

TextBoxIndex = 0;
Text[TextBoxIndex] = "test";
NotifyPropertyChanged("Text[]");

是的,[]是故意的。

更好的方法是使用两个单独的属性。

略有关联:如果您希望在用户仍在输入文字时更新您的媒体资源,请将您的绑定的UpdateSourceTrigger设置为PropertyChangedTextBox.Text默认使用LostFocus(当TextBox失去焦点时更新)。

答案 1 :(得分:0)

设置Text时会触发您的属性更改事件。

text[0] = "test";

这不会调用Text的setter。您需要一行以Text =开头。也就是说,更好的方法是实际拥有两个属性,每个字段一个字符串。拥有一个阵列是没有优势的。