我想将一个ListView绑定到字符串的ObservableCollection,我想用两个可视控件(例如,前缀和这些字符串的后缀)中的数据来修改这些字符串。
一个简化的例子:
XAML:
<TextBox Name="tbPrefix"/>
<TextBox Name="tbPostfix"/>
<ListView Name="lvTarget"/>
C#:
public ObservableCollection<string> sources = GetFromSomewhere();
public IEnumerable<string> Items()
{
foreach (var source in sources)
{
yield return tbPrefix.Text + source + tbPostfix.Text;
}
}
为了更新ListView,我目前只是在CollectionChanged事件上重置它的ItemsSource:
void sources_CollectionChanged(...)
{
lvTarget.ItemsSource = Items();
}
但是我也希望ListView被绑定到它的三个源中的任何一个:集合和前缀/后缀控件。我想我想要一个MultiBinding或MultiDataTrigger,但是我不能完全了解语法和所有我可以找到的将控件绑定到其他控件的例子,而我也有这个ObservableCollection作为源代码。
抱歉,这是我在WPF的第三天,我有点不知所措!谢谢!
发布于 2014-12-29 08:55:23
可观察集合用于通知集合中的项何时更改,如添加、删除、移动等。如果您更改字符串中的文本,它将不会通知。WPF中的第一个最佳实践规则是使用ViewModel绑定属性,而不是后面的代码。您可以通过以下方法解决此问题:
1-创建一个名为SomethingViewModel的新类
2-添加所有需要绑定到视图的属性:
public class SomethingViewModel : INotifyPropertyChanged
{
private string _prefix;
private string _postfix;
public SomethingViewModel()
{
Sources = new ObservableCollection<string>(/*pass initial data of the list*/);
Sources.CollectionChanged += (sender, args) => OnPropertyChanged("Items");
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private ObservableCollection<string> Sources { get; set; }
public IList<string> Items
{
get { return Sources.Select(x => string.Format("{0}{1}{2}", Prefix, x, Postfix)).ToList(); }
}
public string Prefix
{
get
{
return _prefix;
}
set
{
if (_prefix == value) return;
_prefix = value;
OnPropertyChanged("Prefix");
OnPropertyChanged("Items");
}
}
public string Postfix
{
get
{
return _postfix;
}
set
{
if (_postfix == value) return;
_postfix = value;
OnPropertyChanged("Postfix");
OnPropertyChanged("Items"); // we will notify that the items list has changed so the view refresh its items
}
}
}
3-在视图的构造函数中,将以下代码插入视图的数据文本:
public MainWindow()
{
this.DataContext= new SomethingViewModel();
}
4-最后将视图元素绑定到视图模型属性:
<TextBox Text={Binding Prefix,Mode=TwoWay}/>
<TextBox Text={Binding Postfix,Mode=TwoWay}/>
<ListView ItemsSource={Binding Items}/>
5-如果要更改源中的项,不要初始化新对象,只需使用以下方法:
Sources.Clear();
Sources.Add();
发布于 2014-12-29 08:55:04
免责声明:请注意,使用DataTemplate,如克莱门斯的答案,将是更好的解决方案,如果你只需要修改项目的视觉外观。如果您实际上希望将字符串组合成项,那么就按照ViewModel的方式进行。下面的解决方案不是最佳实践,它试图演示MultiBindings如何工作。
这个问题最好在您的ViewModel中解决。只有在绝对必要时才应使用转换器(特别是MultiConverters )。
但是由于这是你使用WPF的第三天,你还不应该被MVVM所困扰。
IEnumerable<string>
作为类型。PrefixPostfixConverter
是什么values
参数传入)中获取输入,并将合并的值创建为数组。发布于 2014-12-29 08:51:28
你不需要任何暗号。只需为DataTemplate项创建适当的ListView:
<ListView ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Text, ElementName=tbPrefix}"/>
<TextBlock Text="{Binding}"/>
<TextBlock Text="{Binding Text, ElementName=tbPostfix}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
注意,Items
在这里是一个公共属性,而不是一个方法,您应该在视图模型类中声明它。该视图模型类的一个实例将分配给视图的DataContext
(例如,MainWindow)。
https://stackoverflow.com/questions/27685395
复制相似问题