2017-12-19 36 views
0

사용자 정의 컨트롤에 문제가 있습니다. 템플릿에서 사용할 때 양방향 바인딩이 작동하지 않습니다. 그래서 내가 만든 템플릿 XAMLWPF TwoWay Binding이 Template의 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

비명 ** (굵은 글자 = 비명 소리)가 필요하지 않지만 작업 바인딩을 위해 INotifyPropertyChanged를 구현하는 것 –

+0

미안하지만 나는 굵게 표시하지 않았다. 나는 메시지 상자 창 텍스트 만 복사했다. –

+0

@IlyaFetisov 나는 당신을 위해 그것을 고쳤다. 다음에 직접 고쳐주세요. –

답변

0

사용자 지정 컨트롤 템플릿의 콤보에서 문제가 발생했습니다. 솔루션은 사용자 지정 컨트롤에서 OnApplyTemplate을 재정의하고 Template.FindName을 사용하여 콤보를 가져온 다음 콤보의 DataContext 개체를 가져 와서 PropertyChanged를 발생시킵니다. 바운드 프롭퍼티의 DataContext 오브젝트 내 문제는 창을로드했을 때 콤보를 업데이트하는 것이 었습니다.