目前我正在尝试实现一个绑定到数据模板(WPF-MVVM)的可观察集合。在初始化期间,它将默认值加载到observable collection。想法是:
目的是跟踪用户更改文本值的时间。
现在正在使用'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);
}
}
增加点数值
答案 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
。string
属性。如果您使用的是早期版本的.NET,则需要将属性名称添加到[CallerMemberName]
调用中。例如:SetProperty()
通过这些更改,您应该能够像这样写SetProperty(ref _count, value, "Count");
:
TestMe()