C# 运行时单向数据绑定。文本的行为类似于一次性
在我的C#/WPF/.net4.5应用程序中,我在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=""/> <Ru
按钮中的文本块中有两个运行。其中一个在其Text
属性上具有数据绑定
<Button x:Name="EditorCommandButton" Margin="10" Padding="5" Height="30" Click="EditorCommandButton_Click">
<TextBlock>
<Run Text=""/>
<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=""/>
<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}" />