ItemsControl DataTemplate不绑定到下划线数据

时间:2019-06-12 16:46:45

标签: c# wpf

我很难将它与收藏夹中的商品进行双向绑定。奇怪的是,该控件显示标签,但是当我在文本框中键入任何内容时,它不会设置下划线值。有人可以告诉我我在做什么错。

        <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>

我尝试了这些不同的类型。

  1. {Binding Path=Value, RelativeSource={RelativeSource Self} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
  2. {Binding XPath=DataContext.Value, RelativeSource={RelativeSource Self} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
  3. {Binding XPath=Value, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
  4. {Binding Path=Value, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}} , Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}

谢谢您的帮助!

编辑: 我被要求为此添加一个更好的示例,因此我创建了一个非常简单的示例。注意:下划线模型被调用,但是不会在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:

    <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>

1 个答案:

答案 0 :(得分:0)

这是一个简化的示例,其中使用ItemsControl,并且属性更新同时起作用。

简单的Data类:

public class Data
{
    public int Id { get; set; }
    public string Name { get; set; }
}

为方便起见,我在INotifyPropertyChanged上实现了MainWindow,但您应该真正使用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;
    }
}

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>

注意:

请检查您的代码是否具有:

  1. 已实施INotifyPropertyChanged
  2. 在列表中使用ObservableCollection