2017-12-19 7 views
0

カスタムコントロールにいくつか問題があります - テンプレートで使用すると双方向バインディングが機能しません。 だから私が作成したテンプレートのXAMLWPF TwoWayバインディングがテンプレートのCustomControlで機能しない

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local="clr-namespace:WpfApp1" 
       xmlns:controls="clr-namespace:GUIControls;assembly=GUIControls" 
       > 

    <ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local="clr-namespace:WpfApp1" 
       xmlns:controls="clr-namespace:GUIControls;assembly=GUIControls" 
       > 

<ControlTemplate x:Key="YParamCombo" TargetType="ContentControl"> 
    <controls:ParamCombo Header="MY CONTROL TEMPLATE" 
    Items="{Binding Items}" 
    PCValue="{Binding Codes[MY_CONTROL_TEMPLATE], Mode=TwoWay}" 
    Required="True" 
    MultiSelect="False"/> 
</ControlTemplate> 

<ControlTemplate x:Key="YComboBox" TargetType="ContentControl"> 
    <ComboBox  DisplayMemberPath="Name" 
    StaysOpenOnEdit="True" 
    ItemsSource="{Binding Items}" 
    SelectedValue="{Binding Codes[STANDARD_TEMPLATE], Mode=TwoWay}" 
    SelectedValuePath="Code"/> 
</ControlTemplate>  

MainWindow.xaml

<Window x:Class="WpfApp1.MainWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:local="clr-namespace:WpfApp1" 
mc:Ignorable="d" 
xmlns:controls="clr-namespace:GUIControls;assembly=GUIControls" 
Title="MainWindow" Height="250" Width="525"> 

<Grid Margin="0,0,0,-1"> 
    <Button Margin="62,162,299,4" Content="Show Codes-1" Click="Button_Click2"></Button> 
    <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
     <HeaderedContentControl Header="STANDARD CONTROL XAML" > 
      <ComboBox DisplayMemberPath="Name" 
       StaysOpenOnEdit="True" 
       ItemsSource="{Binding Items}" 
       SelectedValue="{Binding Codes[STANDARD_XAML]}" 
       SelectedValuePath="Code"/> 
     </HeaderedContentControl> 
     <HeaderedContentControl Header="STANDARD CONTROL TEMPLATE" > 
      <ContentControl Height="23" Template="{StaticResource YComboBox}"/> 
     </HeaderedContentControl> 
     <ContentControl Height="44" Template="{StaticResource YParamCombo}"> 
     </ContentControl> 
     <controls:ParamCombo Header="MY CONTROL XAML" 
      Items="{Binding Items}" 
      PCValue="{Binding Codes[MYCONTROL_XAML], Mode=TwoWay}" 
      Required="True" 
      MultiSelect="False"/> 
    </StackPanel> 
</Grid> 

CS

using System.Linq; 
using System.Windows; 

namespace WpfApp1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      DataContext = new WModel(); 
      InitializeComponent(); 
     } 
     private WModel vm { get { return (DataContext as WModel); } } 
     private void Button_Click2(object sender, RoutedEventArgs e) 
     { 
      MessageBox.Show(string.Join(";", vm.Codes._codes.Select(x => x.Key + "=" + x.Value).ToArray())); 
     } 
    } 
} 

using GUIControls; 
using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
namespace WpfApp1 
{ 
    public class WModel 
    { 
     public WModel() 
     { 
      Codes = new CodesClass(); 
     } 
     public string Caption { get; set; } 
     public ObservableCollection<Dict> Items 
     { 
      get 
      { 
       return new ObservableCollection<Dict>() 
       { 
        new Dict(){ Name = "Name1", Code = "Code1" } , 
        new Dict(){ Name = "Name2", Code = "Code2" } 
       }; 
      } 
     } 
     public CodesClass Codes { get; set; } 
    } 
    public class Dict : IDict 
    { 
     public string Name { get; set; } 
     public string Code { get; set; } 
    } 
    public class CodesClass 
    { 
     public Dictionary<string, object> _codes; 
     public CodesClass() 
     { 
      _codes = new Dictionary<string, object>(); 
     } 
     public object this[string param] 
     { 
      get 
      { 
       if (_codes.ContainsKey(param)) 
        return _codes[param]; 
       else 
        return null;// "I have no " + param; 
      } 
      set 
      { 
       _codes[param] = value; 
      } 
     } 
    } 
} 

私はアプリを実行し、すべての4 Cを選択omboboxesとボタンを押して、私は制御

 public static readonly DependencyProperty PCValueProperty = 
     DependencyProperty.Register("PCValue", typeof(string), typeof(ParamCombo), 
      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPCValuePropertyChanged))); 
    //new PropertyMetadata(new PropertyChangedCallback(OnValuePropertyChanged)));, new PropertyChangedCallback(OnPCValuePropertyChanged)) 
    #endregion 

    private static void OnPCValuePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     ParamCombo paramCombo = (ParamCombo)sender; 
     paramCombo.UpdateSelected((e.NewValue == null) ? "" : e.NewValue.ToString()); 
    } 
からあなたの助けを

感謝を

--------------------------- 

--------------------------- 
STANDARD_XAML=Code2;STANDARD_TEMPLATE=Code2;MYCONTROL_XAML=Code2 
--------------------------- 
ОК 
--------------------------- 

いくつかのコードを動作しません(カスタムコントロールは、テンプレート内で宣言)が双方向で1つのコンボボックスに結合見ることができます!

+1

**悲鳴を上げる必要はありません**(ボールド体の文字=悲鳴を上げる)が、作業バインディングにINotifyPropertyChangedを実装するには –

+0

申し訳ありませんが太字にしていません。メッセージボックスウィンドウのテキストのみをコピーしました。 –

+0

@IlyaFetisov私はあなたのためにそれを修正しました。次回は自分で修正してください。おかげさまで –

答えて

0

カスタムコントロールテンプレートのコンボで問題が発生しました。ソリューションは、カスタムコントロールのOnApplyTemplateをオーバーライドし、Template.FindNameを使用してコンボを取得し、コンボのDataContextオブジェクトを取得し、PropertyChangedを発生させます。バインドされたプロパティのDataContextオブジェクト私の問題は、ウィンドウがロードされたときにコンボを更新することでした。

関連する問題