Run.Text上的单向数据绑定表现得像One Time

时间:2013-12-19 13:59:52

标签: c# wpf xaml data-binding

在我的C#/ WPF / .NET 4.5应用程序中,我在Run的{​​{1}}中有两个TextBlock。其中一个在Button属性上绑定了数据。

Text

最初,<Button x:Name="EditorCommandButton" Margin="10" Padding="5" Height="30" Click="EditorCommandButton_Click"> <TextBlock> <Run Text="&#xE144;"/> <Run Text="{Binding Command, Mode=OneWay, Converter={StaticResource commandConverter}}" /> </TextBlock> </Button> 似乎如此:

当我更新关联对象上的绑定Button属性时...

Command

......它的外观不会改变。

当我重置其父级的数据上下文时......

private void EditorSetCommand_KeyDown(object sender, KeyEventArgs e) {
    MyType g = (MyType)TheEditor.DataContext;
    Key k = e.Key;
    g.Command.Add(e.Key);
    RemoveHandler(Keyboard.KeyDownEvent, (KeyEventHandler)EditorSetCommand_KeyDown);
}

......它更新:

基本上我有一个MyType g = (MyType)TheEditor.DataContext; TheEditor.DataContext = null; TheEditor.DataContext = g; 数据绑定行为类似于OneWay。我该如何解决这个问题?

修改

OneTime类:

myType

转换器:

public class MyType : INotifyPropertyChanged {

    // ...

    private ObservableCollection<Key> _command;

    public ObservableCollection<Key> Command {
        get { return _command; }
        set {
            _command = value;
            OnPropertyChanged("Command");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string propName) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

很明显,您的Text属性未获得更新,因为招标Source不会触发PropertyChanged通知。当您调用g.Command.Add(e.Key);时,您没有更改集合实例,并且OnPropertyChanged("Command");未执行。即使ObservableCollection引发CollectionChanged事件,Run元素也不会监听它,也不会更新它的Text属性。

要快速找到一个难看的解决方案,您可以将KeyDown事件处理程序更改为:

    private void EditorSetCommand_KeyDown(object sender, KeyEventArgs e)
    {
        MyType g = (MyType)TheEditor.DataContext;
        Key k = e.Key;
        g.Command.Add(e.Key);
        g.Command = g.Command;
        RemoveHandler(Keyboard.KeyDownEvent, (KeyEventHandler)EditorSetCommand_KeyDown);
    }

如果你想要一个更优雅的解决方案,我将如何实现这一点。

我将丢失转换器并更改ViewModel类以创建视图需要显示的所有数据:

public class MyType : INotifyPropertyChanged
{
    private ObservableCollection<Key> _command = new ObservableCollection<Key>();
    private string _commandsString = String.Empty;

    public ObservableCollection<Key> Command
    {
        get { return _command; }
    }

    public string CommandsString
    {
        get { return _commandsString; }
        set 
        { 
            _commandsString = value;
            OnPropertyChanged("CommandsString");
        }
    }

    public MyType()
    {
        _command.CollectionChanged += _command_CollectionChanged;
    }

    void _command_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (_command.Count == 0)
            CommandsString = String.Empty;
        else
            CommandsString = " " + string.Join("+", _command);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

XAML中,您绑定到CommandsString String属性:

 <Run Text="{Binding CommandsString, Mode=OneWay}" />