2015-09-29 4 views
0

Создал пользовательский контроль (Autocomplete Lookup), который показывает результаты поиска на основе ключевых слов, которые я печатаю в текстовом поле в раскрывающемся списке.Сопоставление данных в поведении внутри стиля

У меня есть возможность определить шаблоны для части поиска, это текстовое поле, представляющее выбранный элемент, и часть предложения, poput, которая показывает временные результаты.

enter image description here

Изображение показывает, как шаблон предложение выглядит.

В 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> 

Это работает просто отлично. Теперь я хотел показать динамические столбцы в виде сетки. Для этого я сделал поведение, которое получает динамические данные и отображает столбцы по мере необходимости (следующих кодов находится в пределах от выше)

<i:Interaction.Behaviors> 
<mubctrls:DynamicColumnsBehavior GroupColumnsByKey="False"> 
    <mubctrls:DynamicColumnsBehavior.DynamicColumns> 
     <mubctrls:DynamicGridViewColumn 
     Width="Auto" 
     DetailSelector="{Binding Path=Data.SuggestionsViewDynamicColumnSelector, Source={StaticResource Proxy}}"> 

      <mubctrls:DynamicGridViewColumn.HeaderTemplate> 
       <DataTemplate> 
        <!-- The DataContext for the header is represented by the TDynamicColumnKey type. In this case it is UOMLookupResult. --> 
        <TextBlock Text="{Binding UOMName}"/> 
       </DataTemplate> 
      </mubctrls:DynamicGridViewColumn.HeaderTemplate> 

      <mubctrls:DynamicGridViewColumn.CellTemplate> 
       <DataTemplate> 
        <!-- The DataContext for the cells is an instance that has a Root and a Detail property. 
         The Root property refers to the TankSuggestion while the Detail property refers to an instance of TDynamicColumnCellData 
         which in this case is TankUOMQuantity. 
       --> 
        <TextBlock Text="{Binding Detail.DisplayQuantity}"/> 
       </DataTemplate> 
      </mubctrls:DynamicGridViewColumn.CellTemplate> 

     </mubctrls:DynamicGridViewColumn> 
    </mubctrls:DynamicColumnsBehavior.DynamicColumns> 
</mubctrls:DynamicColumnsBehavior> 

я боролся в первой, так как поведение не кажется, быть частью визуального дерева, и поэтому было сложно получить DataContext. По этому вопросу я нашел this article. С помощью упомянутого BindingProxy я могу передать datacontext и привязать к динамическим данным. Все идет нормально. К сожалению, в xaml требуется много кода каждый раз, когда я хочу использовать этот элемент управления, и шаблоны в большинстве случаев идентичны, поэтому я попытался создать стиль для элемента управления. Большинство элементов работают, за исключением динамической части столбца. Я помещаю «Прокси» в раздел, но кажется, что это не работает, потому что не отображаются динамические столбцы (я думаю, что Data.SuggestionsViewDynamicColumnSelector не найден из-за отсутствующего DataContext). Кто-нибудь знает, как поставить код выше в стиле, чтобы заставить его работать правильно? Вот моя попытка:

<Style x:Key="CustomsDetailWithDynamicColumnsStyle" TargetType="{x:Type mubctrls:AutoCompleteLookup}" BasedOn="{StaticResource AutoCompleteLookupBaseStyle}"> 
    <Style.Resources> 
     <mubctrls:BindingProxy x:Key="Proxy" Data="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type mubctrls:AutoCompleteLookup}}}"/> 
    </Style.Resources> 
    <Setter Property="Watermark" Value="{x:Static resources:LabelResources.CustomsDetail}"/> 
    <Setter Property="NoSuggestionsErrorText" 
      Value="{Binding Converter={StaticResource FormatStringConverter}, 
          ConverterParameter={x:Static resources:LabelResources.CustomsDetail}}"/> 
    <Setter Property="LookupTemplate"> 
     <Setter.Value> 
      <DataTemplate DataType="{x:Type customsDetail:CustomsDetailLookupResult}"> 
       <TextBlock> 
        <TextBlock.Text> 
         <MultiBinding StringFormat=" {0} ({1})"> 
          <Binding Path="DocumentNumber"/> 
         </MultiBinding> 
        </TextBlock.Text> 
       </TextBlock> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 

    <Setter Property="SuggestionsView"> 
     <Setter.Value> 
      <GridView x:Name="Test"> 
       <GridViewColumn Header="{x:Static resources:LabelResources.Id}"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding Id}" Foreground="Red" Width="30"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.CustomsLicensePermit}" Width="120"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding PermitName}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.Customer}" Width="150"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding CustomerName}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.ProductClassification}" Width="120"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding ProductClassificationName}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.Tank}" Width="120"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding TankName}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.Origin}" Width="120"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding CountryOfOrigin}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.Date}" Width="120"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding DocumentDate, StringFormat={}{0:MM/dd/yyyy}}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="{x:Static resources:LabelResources.DocumentNumber}" Width="150"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <mubctrls:SuggestionTextBlock Suggestion="{Binding DocumentNumber}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <!-- Definition of the dynamic columns --> 
       <i:Interaction.Behaviors> 
        <mubctrls:DynamicColumnsBehavior GroupColumnsByKey="False"> 
         <mubctrls:DynamicColumnsBehavior.DynamicColumns> 
          <mubctrls:DynamicGridViewColumn 
          Width="Auto" 
          DetailSelector="{Binding Path=Data.SuggestionsViewDynamicColumnSelector, Source={StaticResource Proxy}}"> 

           <mubctrls:DynamicGridViewColumn.HeaderTemplate> 
            <DataTemplate> 
             <!-- The DataContext for the header is represented by the TDynamicColumnKey type. In this case it is UOMLookupResult. --> 
             <TextBlock Text="{Binding UOMName}"/> 
            </DataTemplate> 
           </mubctrls:DynamicGridViewColumn.HeaderTemplate> 

           <mubctrls:DynamicGridViewColumn.CellTemplate> 
            <DataTemplate> 
             <!-- The DataContext for the cells is an instance that has a Root and a Detail property. 
              The Root property refers to the TankSuggestion while the Detail property refers to an instance of TDynamicColumnCellData 
              which in this case is TankUOMQuantity. 
            --> 
             <TextBlock Text="{Binding Detail.DisplayQuantity}"/> 
            </DataTemplate> 
           </mubctrls:DynamicGridViewColumn.CellTemplate> 

          </mubctrls:DynamicGridViewColumn> 
         </mubctrls:DynamicColumnsBehavior.DynamicColumns> 
        </mubctrls:DynamicColumnsBehavior> 
       </i:Interaction.Behaviors> 
      </GridView> 
     </Setter.Value> 
    </Setter>     
</Style> 

Я также попытался изменить связывание DetailSelector с

DetailSelector={Binding Path=SuggestionsViewDynamicColumnSelector, RelativeSource={RelativeSource TemplatedParent}}" 

, но это не сработало.

Извините за длинный пост. Не стесняйтесь спросить

ответ

0

Изменить это <mubctrls:BindingProxy x:Key="Proxy" Data="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type mubctrls:AutoCompleteLookup}}}"/> к <mubctrls:BindingProxy x:Key="Proxy" Data="{Binding}"/>

Вы также должны принять свой ресурс от стиля и поместить его непосредственно в целевой элемент, как так:

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

Это делает все правильно, как ожидается.

+0

не работает либо :(Я изменил Binding к « ', которые приводят к ошибке System.Windows.Data: 2: не удается найти управляющий элемент FrameworkElement или FrameworkContentElement для целевого элемента. BindingExpression: (нет пути); DataItem = null; целевой элемент - «BindingProxy» (HashCode = 12791419); целевое свойство - «Данные» (тип 'Object') – StefanG

+0

Я не уверен, что я не понимаю вас, или вы не получили моей конкретной проблемы. Связующий прокси используется для наследования DataContext для Поведения. Вам это нужно, потому что поведение не является частью VisualTree. Поведение находится внутри стиля, поэтому, следуя вашему примеру, мне нужно будет иметь доступ к {StaticResource Proxy1} внутри стиля выше. Он работает для вас, если вы измените Setter сверху на ? – StefanG

+0

<Сетка х: Name = "MyGrid"> <локальный: BindingProxy х: Key = "proxy1" Data = "{Binding}" />

0

Проблема здесь состоит в два раза:

  1. Как получить доступ к ресурсам внедренные внутри элемента стиля. Это можно сделать следующим образом:

    <Style x:Key="Style1"> 
         <Style.Resources> 
          <SolidColorBrush x:Key="MyColor" Color="Aquamarine"/> 
         </Style.Resources> 
    </Style> 
    

    ...

    <StackPanel Style="{StaticResource Style1}" x:Name="StkPnl"> 
         <Button Width="75" Height="25" Background="{Binding Style.Resources[MyColor], 
             ElementName=StkPnl}"/>    
    </StackPanel> 
    
  2. А теперь как связать ресурс в стиле с BindingProxy. Например, я хочу сделать это в словаре ресурсов/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> 
    

так, что я могу связать некоторое содержание: <Button Content="{Binding Data.Name}" Height="25"/>

Но я не могу сделать это, как связывание разрешен прежде чем стиль станет частью нашей StackPanel. И свойство Data для 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; } 
    } 
} 
+0

@StefanG Я опубликовал этот ответ в ответ на нашу дискуссию в комментариях более раннего ответа. – AnjumSKhan

 Смежные вопросы

  • Нет связанных вопросов^_^