[英]ItemsControl DataTemplate not binding to underlining data
I am having a very difficult time trying to get this to two-way bind to the item in the collection. 我正在努力将其与组合中的项目进行双向绑定。 The strange thing here is that the control shows the label but when I type anything in the text box it doesn't set the underlining value. 这里奇怪的是控件显示标签,但是当我在文本框中输入任何内容时,它不会设置下划线值。 Can someone please tell me what I'm doing wrong here. 有人可以告诉我这里我做错了什么。
<ItemsControl Grid.Row="0" Grid.RowSpan="2" ItemsSource="{Binding QueryObject.RequiredParameters}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type queryModels:QueryObjectParameter}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{Binding Label}"></Label>
<TextBox Grid.Row="1" Text="{Binding Value, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I've tried these different types. 我尝试过这些不同的类型。
{Binding Path=Value, RelativeSource={RelativeSource Self} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
{Binding XPath=DataContext.Value, RelativeSource={RelativeSource Self} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
{Binding XPath=Value, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
{Binding Path=Value, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
Thank you for your help! 谢谢您的帮助!
Edit: I have been asked to add a better example to this so I created a very easy example. 编辑:我被要求添加一个更好的例子,所以我创建了一个非常简单的例子。 Note: the underlining model is called, but it doesn't set the model in the ViewModel. 注意:调用下划线模型,但它不在ViewModel中设置模型。
public class MainWindowViewModel:INotifyPropertyChanged
{
public MainWindowViewModel()
{
PersonQuery = new PersonQuery();
Command = new DelegateCommand(CommandAction);
}
private void CommandAction()
{
MessageBox.Show(PersonQuery.Parameters.First().ToString());
}
public DelegateCommand Command { get; set; }
public PersonQuery PersonQuery { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Parameter
{
public Parameter(string label)
{
Label = label;
}
public string Label { get; set; }
public object Value { get; set; }
public override string ToString()
{
return $"{Label}:{Value}";
}
}
public class PersonQuery
{
public Parameter[] Parameters => new[] {new Parameter("Test"),};
}
XAML: XAML:
<Button Content="Run" Command="{Binding Command}"></Button>
<ItemsControl Grid.Row="1" ItemsSource="{Binding PersonQuery.Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Parameter}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Content="{Binding Label}"></Label>
<TextBox Grid.Row="1" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Here's a simplified example where an ItemsControl
is used and property update works both ways. 这是一个简化的示例,其中使用ItemsControl
并且属性更新以两种方式工作。
Simple Data
class: 简单Data
类:
public class Data
{
public int Id { get; set; }
public string Name { get; set; }
}
Here I implemented INotifyPropertyChanged
on my MainWindow
for convenience, but you should really use a ViewModel and do this there. 为了方便起见,我在我的MainWindow
上实现了INotifyPropertyChanged
,但是您应该使用ViewModel并在那里执行此操作。
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private ObservableCollection<Data> _dataList = null;
public ObservableCollection<Data> DataList
{
get { return _dataList; }
set
{
_dataList = value;
OnPropertyChanged("DataList");
}
}
public MainWindow()
{
InitializeComponent();
DataList = new ObservableCollection<Data>
{
new Data() { Id = 1, Name = "Dan" },
new Data() { Id = 2, Name = "Julie" }
};
DataContext = this;
}
}
The XAML
is super simple: XAML
非常简单:
<ItemsControl ItemsSource="{Binding DataList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding Id}"/>
<TextBox Grid.Column="1" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Check in your code if you have: 如果您有以下内容,请检入您的代码
INotifyPropertyChanged
实现了INotifyPropertyChanged
ObservableCollection
for your list. 对列表使用ObservableCollection
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.