2015-05-06 6 views
0

В настоящее время я пытаюсь реализовать наблюдаемую коллекцию, привязанную к шаблону данных (WPF-MVVM). Во время инициализации он загружает значение по умолчанию в наблюдаемую коллекцию. Идея:Связанное обновление коллекции наблюдаемых без 'RemoveOf' & 'Insert'

  1. Пользователь дает некоторое значение на текстовое поле,
  2. нажимает клавишу ВВОД
  3. увеличивает счетчик и обновляет значение счетчика на TextBlock, который находится рядом с текстовым полем.

Цель состоит в том, чтобы отслеживать, как изменилось текстовое значение пользователем.

Прямо сейчас он работает с 'IndexOf', 'RemoveAt' и 'Insert'. Есть ли способ обойтись без «RemoveAt» и «Insert».

Я чувствую, что что-то не так в моем коде? Может кто-нибудь помочь.

InputDataTemplate.xaml:

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="2*" /> 
     <ColumnDefinition Width="2*" /> 
     <ColumnDefinition Width="1*" /> 
    </Grid.ColumnDefinitions> 

    <Label Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Name}" /> 
    <Label Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Count}" /> 
    <TextBox x:Name="IpDataTb" Grid.Column="1" Width="60" HorizontalAlignment="Center" VerticalAlignment="Center" DataContext="{Binding}" Text="{Binding Path=Data, Mode=TwoWay}"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="KeyDown"> 
       <ei:CallMethodAction TargetObject="{Binding }" MethodName="IpDataTrig" /> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
    </TextBox> 
</Grid> 

TestView.xaml:

<UserControl.Resources> 
    <DataTemplate x:Key="InputDataTemplate" > 
     <local:InputDataTemplate DataContext="{Binding}" /> 
    </DataTemplate> 
</UserControl.Resources> 
<Grid> 
    <Border BorderBrush="#FF0254B4" BorderThickness="1" > 
     <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" > 
      <ItemsControl ItemsSource="{Binding InputDatas}" 
          ItemTemplate="{DynamicResource InputDataTemplate}" /> 
     </ScrollViewer> 
    </Border> 
</Grid> 

DataService.cs:

using MyObsrCollTest.ViewModels; 

namespace MyObsrCollTest.Services 
{ 
    public class InputDataService : BindableBase 
    { 

     public string Name { get; set; } 
     public string Count { get; set; } 
     public string Data { get; set; } 

     public void IpDataTrig(object sender,KeyEventArgs e) 
     { 
      var IpDataTb = new TextBox(); 
      IpDataTb = (TextBox)sender; 

      if ((e.Key == Key.Enter) &&(!string.IsNullOrWhiteSpace(IpDataTb.Text))) 
      { 
       this.Data = IpDataTb.Text; 
       ObsrCollTestVm.TestMe(this.Name, this.Data); 
      } 
     } 
    } 
} 

ObsrCollTestVm.cs:

private ObservableCollection<InputDataService> _InputDatas; 
static int _count = 0; 

public ObsrCollTestVm(void) 
{ 

    for (int i = 0; i < 5; i++) 
    { 

     var l_InputDatas = new InputDataService(); 
     l_InputDatas.Name = i.ToString(); 
     l_InputDatas.Count = "0"; 
     l_InputDatas.Data = "?"; 
     _InputDatas.Add(l_InputDatas); 
    } 
} 

Базовая программа инициализации:

public ObservableCollection<InputDataService> InputDatas 
{ 
    get 
    { 
     if (_InputDatas == null) 
     { 
      _InputDatas = new ObservableCollection<InputDataService>(); 
     } 

     return _InputDatas; 
    } 
} 

Новая коллекция Observable:

public static void TestMe(string name, string data) 
{ 

    var found = _InputDatas.FirstOrDefault(element = > element.Name == name); 
    if (found != null) 
    { 
     int i = _InputDatas.IndexOf(found); 
     found.Count = _count++; 
     _InputDatas.RemoveAt(i); 
     _InputDatas.Insert(i, found); 
    } 
} 

Increment значение счетчика:

ответ

0

Если я правильно понял вопрос правильно, то можно резюмировать следующим образом:

«Я хотел бы быть в состоянии изменить Count свойство моих InputDataService объектов класса и имеют, что изменение отражено в том, что элемент-х Label, без необходимости изменять сам ObservableCollection<InputDataService> ».

Это правильно?

Если это так, то решение предназначено для вашего класса InputDataService, чтобы правильно предоставлять уведомления об изменениях свойств. Обычно это означает либо наследование DependencyObject, либо реализацию ваших свойств в качестве свойств зависимостей, либо просто внедрение интерфейса INotifyPropertyChanged.

Но в вашем примере вы, похоже, уже наследуете класс с именем BindableBase. Если этот класс фактически является классом Microsoft.Practices.Prism.Mvvm.BindableBase, он уже реализует INotifyPropertyChanged, и все, что вам нужно сделать, это воспользоваться этим.

Например:

public class InputDataService : BindableBase 
{ 
    private int _count; 

    public string Name { get; set; } 
    public int Count 
    { 
     get { return _count; } 
     set { SetProperty(ref _count, value); } 
    } 
    public string Data { get; set; } 

    public void IpDataTrig(object sender,KeyEventArgs e) 
    { 
     var IpDataTb = new TextBox(); 
     IpDataTb = (TextBox)sender; 

     if ((e.Key == Key.Enter) &&(!string.IsNullOrWhiteSpace(IpDataTb.Text))) 
     { 
      this.Data = IpDataTb.Text; 
      ObsrCollTestVm.TestMe(this.Name, this.Data); 
     } 
    } 
} 

Примечание:

  • В выше, я только исправил проблему для Count собственности. Вы можете применить аналогичные изменения к другим свойствам, чтобы их правильно обновить.
  • В вашем методе TestMe() вы, кажется, используете свойство Count как int, но оно было объявлено в вашем примере кода как string. Не имея лучшего способа согласования этого несоответствия в вашем примере кода, я только что изменил объявление свойства в приведенном выше примере, чтобы использовать int вместо string.
  • В этом примере предполагается, что вы используете .NET 4.5, в котором поддерживается атрибут [CallerMemberName]. Если вы используете более раннюю версию .NET, вам нужно будет добавить имя свойства в вызов SetProperty(). Например .:
    SetProperty(ref _count, value, "Count");

С этими изменениями, вы должны быть в состоянии написать TestMe() так:

public static void TestMe(string name, string data) 
{ 
    var found = _InputDatas.FirstOrDefault(element = > element.Name == name); 
    if (found != null) 
    { 
     found.Count = _count++; 
    } 
} 
+0

Большое спасибо. Теперь он отлично работает. – kar

+0

Рад слышать, что вы смогли заставить свой код работать. Вам может быть интересно узнать больше о том, как работает Stack Overflow: [Что делать, если кто-то отвечает на мой вопрос?] (Http://stackoverflow.com/help/someone-answers). Дополнительную информацию можно найти по ссылкам на этой странице: http://stackoverflow.com/help/asking –

Смежные вопросы