Sim*_* D. 6 c# data-binding wpf combobox datatemplate
我使用datatemplate来可视化ComboBox中的一些项目,ItemsSource绑定到ObservableCollection.为了简单起见,让我说我把人放入ObservableCollection:
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的DataTemplate看起来像这样:
<DataTemplate TargetType="{x:Type Person}">
<StackPanel Orientation="Horizontal">
<TextSearch.Text>
<MultiBinding StringFormat="{} {0} {1}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextSearch.Text>
<TextBlock Text="{Binding FirstName}" Margin="2,0" />
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
现在我想在ComboBox中为全名启用自动完成功能,而不在我的person类上引入第三个属性.因此我不想在ComboBox上使用TextSearch.TextPath属性,而是想在DataTemplate中绑定每个ComboBoxItem的TextSearch.Text-Property.不幸的是,当我这样做(使用MultiBinding和StringFormat,使用Snoop测试)时,绑定值仅为我的StackPanel注册,但是使用Snoop(很棒的工具)我发现这个stackpanel就像其他一些ComboBoxItemTemplate的内容一样,它放置另一个边框等,最后一个ComboBoxItem标签围绕我的外部StackPanel.因此,TextSearch.Text设置无效,因为它必须在创建的ComboBoxItem中设置,而不是在其中的某个位置.
现在问题:如何使用XAML-Styles和-Control-Templates将我的DataTemplate中的TextSearch.Text-Property传播到周围的ComboBoxItem?该解决方案可能会修改ComboBox和ComboBoxItem的默认ControlTemplates以及我的自定义(Item-)DataTemplate,但不会使用任何Code-Behind,或者至少不会太多.也许附加的行为也可以.但我几乎肯定必须有一种方法可以让它无需工作,TemplateBinding或RelativeSource-stuff ......当然,解决方案必须使我的键盘选择和文本完成工作,s.当名单中包含汉斯约瑟夫和汉斯彼得,然后进入'汉斯'应该自动提出汉斯约瑟夫,而进入'汉斯P'足够快应该自动提出汉斯彼得.
有解决方案吗
简短回答:您想要做的事情不能直接在XAML中完成,但还有其他方法可以做到.
答案很长:ComboBox直接在Items或ItemsSource集合中存储的数据项中查找TextSearch.Text属性.因此,您无法在数据模板或样式中设置属性,因为它们适用于用于显示数据项的对象,而不适用于数据项本身.
特别是,如果查看TextSearch类页面上的示例,您将看到它们将TextSearch.Text属性附加到进入ComboBox.Items集合的Image对象.您可以通过使Person成为DependencyObject在您的程序中执行此操作,但我认为您不希望在每个单独的对象上设置该属性.
你有几个选择:
如果可以修改Person类,则可以定义ToString()方法以将文本返回到自动完成或定义任意属性(如Fullname)并在ComboBox上设置Textsearch.TextPath.例如:
public class Person
{
string FirstName { get; set; }
string LastName {get; set; }
string FullName { get { return String.Format("{0} {1}", FirstName, LastName); } }
}
Run Code Online (Sandbox Code Playgroud)
和
<ComboBox TextSearch.TextPath="FullName" ItemsSource="collectionOfPersons"/>
Run Code Online (Sandbox Code Playgroud)
另外,如果您不想触摸Person,可以创建一个公开这些属性的包装类.
面板周围的东西是默认容器。您需要将 TextSearch.Text 属性应用于容器。您应该能够通过 ItemContainerStyle 设置属性来做到这一点,如下所示:
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="TextSearch.Text">
<Setter.Value>
<MultiBinding StringFormat="{} {0} {1}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8919 次 |
| 最近记录: |