문제

이 마크 업이 있습니다.

   <GroupBox BorderThickness="2">
    <GroupBox.BorderBrush>
        <SolidColorBrush x:Name="Border">
            <SolidColorBrush.Color>
                <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
                    <Binding Path="IsConnected"/>
                    <Binding Path="IsLoggedIn"/>
                </MultiBinding>
            </SolidColorBrush.Color>
        </SolidColorBrush>
    </GroupBox.BorderBrush>

뒤에있는 코드 에서이 줄은 window_loaded 메소드에 다음과 같습니다.

DataContext = uiManager;

Uimanager는 isconnected와 isloggedin이라는 두 개의 공개 속성을 가진 유형의 Uimanager입니다.

Multibinding에서 호출되는 컨버터의 값 배열은 부울로 채워지지 않지만 종속성 property.unsetValue의 값이 있기 때문에이 코드는 시작 시점에 실패합니다.

아래 마크 업을 사용하면 (변환기의 returnType를 변경) 작동합니다.

   <GroupBox BorderThickness="2">
    <GroupBox.BorderBrush>
         <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
              <Binding Path="IsConnected"/>
              <Binding Path="IsLoggedIn"/>
         </MultiBinding>
    </GroupBox.BorderBrush>

바인딩이 첫 번째 예제에서는 코드의 Datacontext를 통해 설정된 바인딩이 실패하지만 두 번째 예제에서는 작동하는 것으로 보입니다. 왜요?

Uimanager 클래스 이하의 완전성 :

public class UIManager:IUIManager
    {

        #region Implementation of IUIManager

        private const string IsLoggedInProperty = "IsLoggedIn";
        private bool loggedIn;
        private readonly object loggedInLock = new object();
        public bool IsLoggedIn
        {
            get
            {
                lock (loggedInLock)
                {
                    return loggedIn;
                }
            }
            set
            {
                lock (loggedInLock)
                {
                    if(value==loggedIn)return;
                    loggedIn = value;
                    OnPropertyChanged(IsLoggedInProperty);
                }
            }
        }

        private void OnPropertyChanged(string property)
        {
            if(PropertyChanged!=null)PropertyChanged(this,new PropertyChangedEventArgs(property));
        }

        private const string IsConnectedProperty = "IsConnected";
        private bool isConnected;
        private object isConnectedLock = new object();
        public bool IsConnected
        {
            get
            {
                lock (isConnectedLock)
                {
                    return isConnected;
                }
            }
            set
            {
                lock (isConnectedLock)
                {
                    if(value==isConnected)return;
                    isConnected = value;
                    OnPropertyChanged(IsConnectedProperty);
                }
            }
        }

        #endregion

        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

편집 : 실패한 XAML에 대한 변환 방법 (값의 부리로 변환에 실패 [0] :

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var is_connected = (bool) values[0];
            var is_loggedin = (bool) values[1];
            return is_loggedin
                       ? is_connected
                             ? Colors.YellowGreen
                             : Colors.Red
                       : Colors.Gray;
        }

작동하는 XAML의 경우 :

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var is_connected = (bool) values[0];
            var is_loggedin = (bool) values[1];
            return is_loggedin
                       ? is_connected
                             ? Brushes.YellowGreen
                             : Brushes.Red
                       : Brushes.Gray;
        }
도움이 되었습니까?

해결책

문제는 a와 관련이 없습니다 MultiBinding 또는 변환기. DependencyProperty.UnsetValue 바인딩의 가치가 없음을 의미합니다. 실제로 디버그 모드에서 실행되면 바인딩 오류가 Output 창문:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsConnected; DataItem=null; target element is 'SolidColorBrush' (HashCode=17654054); target property is 'Color' (type 'Color')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsLoggedIn; DataItem=null; target element is 'SolidColorBrush' (HashCode=17654054); target property is 'Color' (type 'Color')

마크 업을 조금 단순화하고 진단을 적용합시다.

<GroupBox>
    <GroupBox.BorderBrush>
        <SolidColorBrush>
            <SolidColorBrush.Color>
                <Binding Path="GroupColor" PresentationTraceSources.TraceLevel="High"/>
            </SolidColorBrush.Color>
        </SolidColorBrush>
    </GroupBox.BorderBrush>
</GroupBox>

첨부 된 종속성 속성 적용 PresentationTraceSources.TraceLevel 더 많은 출력을 얻습니다.

System.Windows.Data Warning: 52 : Created BindingExpression (hash=17654054) for Binding (hash=44624228)
System.Windows.Data Warning: 54 :   Path: 'GroupColor'
System.Windows.Data Warning: 56 : BindingExpression (hash=17654054): Default mode resolved to OneWay
System.Windows.Data Warning: 57 : BindingExpression (hash=17654054): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 58 : BindingExpression (hash=17654054): Attach to System.Windows.Media.SolidColorBrush.Color (hash=52727599)
System.Windows.Data Warning: 60 : BindingExpression (hash=17654054): Use Framework mentor <null>
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Warning: 61 : BindingExpression (hash=17654054): Resolve source deferred
System.Windows.Data Warning: 91 : BindingExpression (hash=17654054): Got InheritanceContextChanged event from SolidColorBrush (hash=52727599)
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 66 : BindingExpression (hash=17654054): Found data context element: GroupBox (hash=51393439) (OK)
System.Windows.Data Warning: 67 : BindingExpression (hash=17654054): DataContext is null
System.Windows.Data Warning: 91 : BindingExpression (hash=17654054): Got InheritanceContextChanged event from SolidColorBrush (hash=52727599)
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source  (last chance)
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=GroupColor; DataItem=null; target element is 'SolidColorBrush' (HashCode=52727599); target property is 'Color' (type 'Color')

우리는 바인딩이 a를 찾지 못한다는 것을 알 수 있습니다 DataContext 그리고 바인딩이 실패합니다. Windows의 생성자를 변경할 때 DataContext 컨텐츠를 초기화하기 전에 설정되어 바인딩이 작동합니다.

public Window1()
{
    DataContext = ...;
    InitializeComponent();
}

다른 곳에서 바인딩을 위해서는 이상하지 않습니다. 이것은 중요하지 않습니다. 왜 거기에서 작동하지 않으므로 해결 방법 만 제공 할 수 있습니다. 예를 들어 효과가있는 것은 바인딩이있는 자원으로 브러시를 만드는 것입니다 (그 자원은 또한 로컬에있을 수 있습니다. GroupBox):

<GroupBox BorderBrush="{DynamicResource resbrush}">
    <GroupBox.Resources>
        <SolidColorBrush x:Key="resbrush">
            <SolidColorBrush.Color>
                <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
                    <Binding Path="IsConnected"/>
                    <Binding Path="IsLoggedIn"/>
                </MultiBinding>
            </SolidColorBrush.Color>
        </SolidColorBrush>
    </GroupBox.Resources>
</GroupBox>

나는 그것을 떨어 뜨릴 것을 제안한다 MultiBinding 그리고 몇 가지 사전 프로세싱을 수행합니다 DataContext 당신의 경우 UIManager 수업은 일종의 것입니다 MVVM ViewModel.

다른 팁

내 이론. 색상은 구조 (null이 될 수 없음)이므로 solidcolorbrush.color = null이 잘못되었습니다. WPF는 SolidColorBrush를 만들 수 없으며 예외가 발생합니다.

 <GroupBox.BorderBrush>
     <SolidColorBrush x:Name="Border">
         <SolidColorBrush.Color>
             <MultiBinding Converter="{StaticResource 
                           ConnectionAndLoggedInToBorderBrush}">
                 <Binding Path="IsConnected"/>
                 <Binding Path="IsLoggedIn"/>
             </MultiBinding>
         </SolidColorBrush.Color>
     </SolidColorBrush>
 </GroupBox.BorderBrush>

BorderBrush는 객체 (null이 될 수 있음)이므로 Groupbox.borderBrush = null은 괜찮습니다.

 <GroupBox.BorderBrush>
      <MultiBinding Converter="{StaticResource 
                    ConnectionAndLoggedInToBorderBrush}">
           <Binding Path="IsConnected"/>
           <Binding Path="IsLoggedIn"/>
      </MultiBinding>
 </GroupBox.BorderBrush>

이 solidcolorbrush는 물체가 아니라 공장입니다. 필요할 때만 인스턴스화되며, 그 시점에서 이미 Datacontext를 첨부했습니다.

 <GroupBox.Resources>
      <SolidColorBrush x:Key="resbrush">
           <SolidColorBrush.Color>
                <MultiBinding Converter="{StaticResource 
                              ConnectionAndLoggedInToBorderBrush}">
                     <Binding Path="IsConnected"/>
                     <Binding Path="IsLoggedIn"/>
                </MultiBinding>
           </SolidColorBrush.Color>
      </SolidColorBrush>
 </GroupBox.Resources>

내 2 센트.

내 기사 BTW를 읽으십시오. 이상한 컨버터가있는 이상한 바인딩이나 애니메이션이 필요한 경우 유용 할 수 있습니다. http://www.codeproject.com/kb/wpf/bindinghub.aspx

MVVM 학습을 고려하고 싶을 수도있는 이유입니다. 이 패턴을 사용하면 모델과 바인딩을 추출하여 DPS에 크게 의존 할 필요가 없습니다. 대신 뷰 모델에서 알 수없는 속성에 단순히 바인딩 할 수 있습니다.

MVVM에는 몇 가지 훌륭한 기사가 있으므로 Karl Shifflett, Josh Smith, Marlon Grech 및 Sacha Barber의 작품을 읽는 것으로 시작하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top