没有'RemoveOf'和&amp ;;绑定的可观察集合更新'插入'

时间:2015-05-06 23:02:38

标签: c# mvvm textbox observablecollection

目前我正在尝试实现一个绑定到数据模板(WPF-MVVM)的可观察集合。在初始化期间,它将默认值加载到observable collection。想法是:

  1. 用户在文本框中提供了一些值,
  2. 按ENTER键
  3. 递增计数器并更新位于文本框附近的文本块上的计数值。
  4. 目的是跟踪用户更改文本值的时间。

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

    增加点数值

1 个答案:

答案 0 :(得分:0)

如果我正确理解了这个问题,可以概括为:

  

“我希望能够更改Count类对象的InputDataService属性,并将该更改反映在该项Label中,而无需修改{{1}本身。“

这是对的吗?

如果是,那么解决方案是让您的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
  • 此示例假定您使用的是.NET 4.5,其中支持string属性。如果您使用的是早期版本的.NET,则需要将属性名称添加到[CallerMemberName]调用中。例如:
    SetProperty()

通过这些更改,您应该能够像这样写SetProperty(ref _count, value, "Count");

TestMe()