ItemsControl DataTemplate не привязан к подчеркиванию данных - PullRequest
0 голосов
/ 12 июня 2019

У меня очень тяжелые времена, когда я пытаюсь связать это с предметом в коллекции. Странная вещь в том, что элемент управления показывает метку, но когда я что-то печатаю в текстовом поле, он не устанавливает подчеркивание. Может кто-нибудь, пожалуйста, скажите мне, что я делаю здесь не так.

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

Спасибо за помощь!

Edit: Меня попросили добавить лучший пример к этому, поэтому я создал очень простой пример. Примечание: вызывается подчеркивающая модель, но она не устанавливает модель во 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 голосов
/ 12 июня 2019

Вот упрощенный пример, где используется 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 для вашего списка.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...