Wpf 样式内行为的数据绑定

Wpf 样式内行为的数据绑定,wpf,xaml,data-binding,behavior,Wpf,Xaml,Data Binding,Behavior,我创建了一个customcontrol自动完成查找,它根据我在底层弹出窗口的文本框中键入的关键字显示搜索结果 我可以为查找部分定义模板,即表示所选项目的文本框和显示临时结果的建议部分 此图显示了建议模板的外观 在xaml中,您可以这样定义模板 <controls:AutoCompleteLookup Watermark="Tank" Provider={Binding TankProvider} SelectedItem={Binding SelectedCusto

我创建了一个customcontrol自动完成查找,它根据我在底层弹出窗口的文本框中键入的关键字显示搜索结果

我可以为查找部分定义模板,即表示所选项目的文本框和显示临时结果的建议部分

此图显示了建议模板的外观

在xaml中,您可以这样定义模板

<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; }
    }
}