Wpf 样式内行为的数据绑定
我创建了一个customcontrol自动完成查找,它根据我在底层弹出窗口的文本框中键入的关键字显示搜索结果 我可以为查找部分定义模板,即表示所选项目的文本框和显示临时结果的建议部分 此图显示了建议模板的外观 在xaml中,您可以这样定义模板Wpf 样式内行为的数据绑定,wpf,xaml,data-binding,behavior,Wpf,Xaml,Data Binding,Behavior,我创建了一个customcontrol自动完成查找,它根据我在底层弹出窗口的文本框中键入的关键字显示搜索结果 我可以为查找部分定义模板,即表示所选项目的文本框和显示临时结果的建议部分 此图显示了建议模板的外观 在xaml中,您可以这样定义模板 <controls:AutoCompleteLookup Watermark="Tank" Provider={Binding TankProvider} SelectedItem={Binding SelectedCusto
<controls:AutoCompleteLookup
Watermark="Tank"
Provider={Binding TankProvider}
SelectedItem={Binding SelectedCustomer}>
<controls:AutoCompleteLookup.LookupTemplate>
<DataTemplate DataType="{x:Type providers:TankLookupResult}">
<TextBlock Text="{Binding TankName}"/>
</DataTemplate>
</controls:AutoCompleteLookup.LookupTemplate>
<controls:AutoCompleteLookup.SuggestionsView>
<GridView x:Key="ContractStorageDetailGridView" x:Shared="False">
<GridViewColumn Header="Tank" Width="Auto" HeaderContainerStyle="{StaticResource GridViewHeaderStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<mubctrls:SuggestionTextBlock Suggestion="{Binding TankName}" Foreground="Red"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Int. Reference" Width="Auto" HeaderContainerStyle="{StaticResource GridViewHeaderStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding InternalReference}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Customer" Width="Auto" HeaderContainerStyle="{StaticResource GridViewHeaderStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</controls:AutoCompleteLookup.SuggestionTemplate>
</controls:AutoCompleteLookup>
但它也不起作用
抱歉发了这么长的邮件。请随时询问将此更改为
您还必须从样式中取出资源,并将其直接放入目标元素中,如下所示:
<Window.Resources>
<Style TargetType="Grid">
<Setter Property="Background" Value="AliceBlue"/>
</Style>
</Window.Resources>
<Grid x:Name="MyGrid">
<Grid.Resources>
<local:BindingProxy x:Key="Proxy1" Data="{Binding}" />
</Grid.Resources>
<Button Content="{Binding Data.Name, Source={StaticResource Proxy1}}" Margin="45,135,26,136"/>
</Grid>
这一切都如预期的那样正确。这里的问题有两个方面: 如何访问嵌入在样式元素中的资源。可以这样做:
<Style x:Key="Style1">
<Style.Resources>
<SolidColorBrush x:Key="MyColor" Color="Aquamarine"/>
</Style.Resources>
</Style>
现在介绍如何将资源以样式绑定到BindingProxy。例如,我想在resource dictionary/window.resources中执行此操作:
<Style x:Key="MyStyle">
<Style.Resources>
<local:BindingProxy x:Key="Proxy" Data="{Binding}"/>
<SolidColorBrush x:Key="Brush2" Color="{Binding Data.Color ,Source={StaticResource Proxy}}"/>
</Style.Resources>
</Style>
这样我就可以绑定一些内容:
但我不能这样做,因为在样式成为StackPanel的一部分之前,绑定已经解决了。而BindingProxy的数据属性将为null,因为样式是在外部定义的。解决此问题的一种方法是将所有内容都置于主数据显示控制之下
如果您希望将事情分开,解决方法如下:
<Window ...>
<Window.Resources>
<!-- Employee placeholder to allow for declarative binding. It's properties will be filled in code -->
<local:Employee x:Key="Emp"/>
<!-- Binding proxy to Employee / Viewmodel -->
<local:BindingProxy x:Key="Proxy" Data="{Binding (Window.Resources)[Emp], RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
<Style x:Key="MyStyle">
<Style.Resources>
<!-- Here Color property is bound using BindingProxy -->
<SolidColorBrush x:Key="Brush2" Color="{Binding Data.Color ,Source={StaticResource Proxy}}"/>
</Style.Resources>
</Style>
</Window.Resources>
<StackPanel x:Name="Pnl1" Style="{StaticResource MyStyle}">
<Button Content="{Binding Data.Name, Source={StaticResource Proxy}}" Background="{Binding Style.Resources[Brush2], ElementName=Pnl1}" Height="25" Width="75"/>
</StackPanel>
</Window>
MainWindow.xaml.cs
namespace ...
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Employee emp = (Employee)this.Resources["Emp"];
emp.Name = "StackOverflow";
emp.Address = "USA";
emp.Color = "Orange";
//Pnl1.DataContext = emp;
}
}
public class Employee
{
public String Name { get; set; }
public String Address { get; set; }
public String Color { get; set; }
}
}
也不起作用:我更改了give System.Windows.Data的绑定错误:2:找不到目标元素的治理FrameworkElement或FrameworkContentElement。BindingExpression:无路径;DataItem=null;目标元素是'BindingProxy'HashCode=12791419;目标属性为“数据”类型“对象”,我不确定我是否不理解您的意思,或者您是否了解我的具体问题。绑定代理用于将DataContext继承到行为。您需要这个,因为行为不是VisualTree的一部分。该行为位于样式内部,因此根据您的示例,我需要访问上述样式内部的{StaticResource Proxy1}。如果你把上面的二传手换成了,对你有用吗?这很有魅力。试试这个,否则我会提出一个更好的解决方案。你是对的,这个简单的例子很有效。但是在我的例子中,如果我没有使用样式,那么它可以工作,但是一旦我将代理绑定从FindAncestor更改为{binding},它就不再工作了:。以你为例。如果你想在单独的资源字典中移动样式,你会怎么做?我正在开发一个示例应用程序,使用行为和样式解决你的问题。等等。@StefanG我已经发布了这个答案,以回应我们在早期答案评论中的讨论。
<StackPanel Style="{StaticResource Style1}" x:Name="StkPnl">
<Button Width="75" Height="25" Background="{Binding Style.Resources[MyColor],
ElementName=StkPnl}"/>
</StackPanel>
<Style x:Key="MyStyle">
<Style.Resources>
<local:BindingProxy x:Key="Proxy" Data="{Binding}"/>
<SolidColorBrush x:Key="Brush2" Color="{Binding Data.Color ,Source={StaticResource Proxy}}"/>
</Style.Resources>
</Style>
<Window ...>
<Window.Resources>
<!-- Employee placeholder to allow for declarative binding. It's properties will be filled in code -->
<local:Employee x:Key="Emp"/>
<!-- Binding proxy to Employee / Viewmodel -->
<local:BindingProxy x:Key="Proxy" Data="{Binding (Window.Resources)[Emp], RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
<Style x:Key="MyStyle">
<Style.Resources>
<!-- Here Color property is bound using BindingProxy -->
<SolidColorBrush x:Key="Brush2" Color="{Binding Data.Color ,Source={StaticResource Proxy}}"/>
</Style.Resources>
</Style>
</Window.Resources>
<StackPanel x:Name="Pnl1" Style="{StaticResource MyStyle}">
<Button Content="{Binding Data.Name, Source={StaticResource Proxy}}" Background="{Binding Style.Resources[Brush2], ElementName=Pnl1}" Height="25" Width="75"/>
</StackPanel>
</Window>
namespace ...
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Employee emp = (Employee)this.Resources["Emp"];
emp.Name = "StackOverflow";
emp.Address = "USA";
emp.Color = "Orange";
//Pnl1.DataContext = emp;
}
}
public class Employee
{
public String Name { get; set; }
public String Address { get; set; }
public String Color { get; set; }
}
}