C# 运行时单向数据绑定。文本的行为类似于一次性

C# 运行时单向数据绑定。文本的行为类似于一次性,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,在我的C#/WPF/.net4.5应用程序中,我在按钮中的文本块中有两个运行。其中一个在其Text属性上具有数据绑定 <Button x:Name="EditorCommandButton" Margin="10" Padding="5" Height="30" Click="EditorCommandButton_Click"> <TextBlock> <Run Text="&#xE144;"/> <Ru

在我的C#/WPF/.net4.5应用程序中,我在
按钮中的
文本块中有两个
运行。其中一个在其
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>
…它的外观没有改变

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

MyType g = (MyType)TheEditor.DataContext;
TheEditor.DataContext = null;
TheEditor.DataContext = g;
…它更新了:

本质上,我有一个单向的数据绑定,其行为类似于一次性的。如何修复此行为

编辑:

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));
        }
    }
}
公共类MyType:INotifyPropertyChanged{
// ...
私有observeCollection_命令;
公共可观测集合命令{
获取{return\u命令;}
设置{
_命令=值;
OnPropertyChanged(“命令”);
}
}
公共事件属性更改事件处理程序属性更改;
void OnPropertyChanged(字符串propName){
if(PropertyChanged!=null){
PropertyChanged(这是新PropertyChangedEventArgs(propName));
}
}
}
转换器:

[ValueConversion(typeof(ObservableCollection<Key>), typeof(string))]
public class CommandConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        ObservableCollection<Key> c = (ObservableCollection<Key>)value;
        if (c.Count == 0) return "";
        else return " " + string.Join("+", c);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}
[ValueConversion(typeof(observetecollection)、typeof(string))]
公共类CommandConverter:IValueConverter{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性){
ObservableCollection c=(ObservableCollection)值;
如果(c.Count==0)返回“”;
否则返回“+string.Join(“+”,c);
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性){
抛出新的NotImplementedException();
}
}

很明显,您的
文本
属性不会得到更新,因为出价
不会触发
属性更改
通知。当您调用
g.Command.Add(e.Key)时
您没有更改集合实例和您的
OnPropertyChanged(“命令”)不会被执行。即使
observateCollection
引发
CollectionChanged
事件,
Run
元素也不会侦听它,也不会更新它的文本属性

<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>
要快速获得丑陋的解决方案,您可以将
KeyDown
eventhandler更改为:

    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));
        }
    }
}

使用Command属性发布
MyType
的实现,这是一个
observedcollection
?@NovitchiS我在上面添加了它
MyType
还有其他可观察的属性,它们工作正常。我猜,既然它是一个集合,您需要一个集合更改通知。
 <Run Text="{Binding CommandsString, Mode=OneWay}" />