2015-05-06 86 views
0

目前我试图实现一个绑定到数据模板(WPF-MVVM)的可观察集合。在初始化期间,它将默认值加载到可观察集合中。思想是:绑定可观察的集合更新没有'RemoveOf'和'插入'

  1. 用户提供的文本框中某个值,
  2. 按ENTER键
  3. 递增计数器和位于附近的文本框中输入文本块更新的计数值。

目的是跟踪用户更改文本值的次数。

现在它正在使用'IndexOf','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; 
    } 
} 

新观察到的集合:

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

递增计数值:

回答

0

如果我理解正确的问题,它可以概括为:

“我希望能够改变我的InputDataService类对象的Count财产,有一个变化体现在该项目的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 –