programing

손상된 WPF 데이터 바인딩을 탐지하는 방법은 무엇입니까?

easyjava 2023. 4. 29. 10:02
반응형

손상된 WPF 데이터 바인딩을 탐지하는 방법은 무엇입니까?

'WPF 바인딩을 테스트하는 장치' 근처의 질문에 답하려고 하는 동안 다음과 같은 사소한 질문이 있었습니다.
WPF 데이터 바인딩 배선이 잘못 설정되어 있거나 올바르게 배선된 것이 손상된 경우 가장 좋은 방법은 무엇입니까?

비록 유닛 테스트 접근법이 Joel의 '팔뚝을 잘라 가시를 제거하는' 것처럼 보이지만..저는 이것을 감지할 수 있는 더 쉬운 간접비 방법을 찾고 있습니다.

모든 사람들이 WPF를 통해 데이터 바인딩을 크게 하기로 약속한 것 같습니다.그리고 그것은 장점이 있습니다.

3바인딩에 되었습니다.NET 3.5에서는 특정 데이터 바인딩에 대한 추적 정보를 출력하는 새로운 방법이 도입되었습니다.

작업은 새 시스템을 통해 수행됩니다.진단.프레젠테이션 추적 소스입니다.바인딩 또는 데이터 공급자에 적용할 수 있는 TraceLevel 연결 속성입니다.다음은 예입니다.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    Title="Debug Binding Sample"
    Height="300"
    Width="300">
    <StackPanel>
        <TextBox Name="txtInput" />
        <Label>
            <Label.Content>
                <Binding ElementName="txtInput"
                         Path="Text"
                         diag:PresentationTraceSources.TraceLevel="High" />
            </Label.Content>
        </Label>
    </StackPanel>
</Window>

이렇게 하면 추적 구성 없이 Visual Studio의 출력 창에 해당 바인딩에 대한 추적 정보만 표시됩니다.

내가 찾을 수 있는 최선은...

어떻게 하면 WPF 바인딩을 디버깅할 수 있습니까? by Beatriz Stollnitz

모든 사람이 Binding 오류를 찾기 위해 출력 창을 항상 주시할 수는 없기 때문에 옵션 #2가 좋았습니다.이것을 앱에 추가하는 것입니다.구성

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.Windows.Data" switchName="SourceSwitch" >
        <listeners>
          <add name="textListener" />
        </listeners>
      </source>

    </sources>
      <switches>
        <add name="SourceSwitch" value="All" />
      </switches>

      <sharedListeners>
        <add name="textListener"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="GraveOfBindErrors.txt" />
      </sharedListeners>

      <trace autoflush="true" indentsize="4"></trace>

  </system.diagnostics>
</configuration>

GraveOfBindErrors에서 가끔 실행할 수 있도록 적절한 정규식 검색 스크립트와 연결하여 관련 정보를 추출합니다.출력 폴더의 txt

System.Windows.Data Error: 35 : BindingExpression path error: 'MyProperty' property not found on 'object' ''MyWindow' (Name='')'. BindingExpression:Path=MyProperty; DataItem='MyWindow' (Name=''); target element is 'TextBox' (Name='txtValue2'); target property is 'Text' (type 'String')

여기에 제시된 솔루션을 사용하여 바인딩 오류를 기본 예외로 전환합니다. http://www.jasonbock.net/jb/Default.aspx?blog=entry.0f221e047de740ee90722b248933a28d

그러나 WPF 바인딩의 일반적인 시나리오는 사용자 입력을 대상 유형으로 변환할 수 없는 경우(예: 정수 필드에 바인딩된 TextBox; 숫자가 아닌 문자열의 입력은 FormatException, 숫자가 너무 큰 입력은 Overflow를 초래함) 예외를 발생시키는 것입니다.예외).소스 속성의 Setter가 예외를 던지는 경우도 이와 유사합니다.

WPF는 ValidateOnExceptions=true 및 Validation을 통해 이 문제를 처리합니다.예외 규칙 - 제공된 입력이 올바르지 않음을 사용자에게 알리기 위한 규칙입니다(예외 메시지 사용).

그러나 이러한 예외는 출력 창에도 전송되므로 BindingListener에 의해 '걸려' 오류가 발생합니다. 명백히 원하는 동작이 아닙니다.

그러므로, 저는 그것을 확장했습니다.BindingListener다음과 같은 경우 예외를 던지지 않도록 클래스:

private static readonly IList<string> m_MessagesToIgnore =
        new List<String>()
        {
            //Windows.Data.Error 7
            //Binding transfer from target to source failed because of an exception
            //Normal WPF Scenario, requires ValidatesOnExceptions / ExceptionValidationRule
            //To cope with these kind of errors
            "ConvertBack cannot convert value",

            //Windows.Data.Error 8
            //Binding transfer from target to source failed because of an exception
            //Normal WPF Scenario, requires ValidatesOnExceptions / ExceptionValidationRule
            //To cope with these kind of errors
            "Cannot save value from target back to source"  
        };

공용의 수정된 행이 void WriteLine(문자열 메시지)을 재정의합니다.

        ....
        if (this.InformationPropertyCount == 0)
        {
            //Only treat message as an exception if it is not to be ignored
            if (!m_MessagesToIgnore.Any(
                x => this.Message.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)))
            {
                PresentationTraceSources.DataBindingSource.Listeners.Remove(this);

                throw new BindingException(this.Message,
                    new BindingExceptionInformation(this.Callstack,
                        System.DateTime.Parse(this.DateTime),
                        this.LogicalOperationStack, int.Parse(this.ProcessId),
                        int.Parse(this.ThreadId), long.Parse(this.Timestamp)));
            }
            else
            {
                //Ignore message, reset values
                this.IsFirstWrite = true;
                this.DetermineInformationPropertyCount();
            }
        }
    }

WPF Inspector의 트리거 디버깅 기능을 사용할 수 있습니다.코드플렉스에서 도구를 다운로드하여 실행 중인 앱에 첨부하기만 하면 됩니다.또한 창 하단에 바인딩 오류가 표시됩니다.매우 유용한 도구!

여기에 이미지 설명 입력

다음은 트리거를 효과적으로 디버깅/추적하기 위한 유용한 기술입니다.모든 트리거 작업을 작업 대상 요소와 함께 기록할 수 있습니다.

http://www.wpfmentor.com/2009/01/how-to-debug-triggers-using-trigger.html

이것은 우리에게 매우 도움이 되었지만 Microsoft가 이 파일을 읽기 위해 sdk와 함께 제공하는 유틸리티가 있다는 것을 유용하다고 생각하는 사람들에게 추가하고 싶습니다.

다음 위치: http://msdn.microsoft.com/en-us/library/ms732023.aspx

추적 파일 열기

1.명령 창을 사용하여 WCF 설치 위치(C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin)로 이동한 다음 SvcTraceViewer.exe를 입력합니다.(\v7.0\Bin에서 우리의 것을 찾았지만)

참고: Service Trace Viewer 도구는 .svclog 및 .stvproj의 두 가지 파일 유형과 연결할 수 있습니다.명령줄에서 두 개의 매개 변수를 사용하여 파일 확장명을 등록 및 등록 취소할 수 있습니다.

/register: 파일 확장명 ".svclog" 및 ".stvproj"의 연결을 SvcTraceViewer에 등록합니다.exe

/unregister: 파일 확장명 ".svclog" 및 ".stvproj"와 SvcTraceViewer의 연결을 등록 취소합니다.exe

1.서비스 추적 뷰어가 시작되면 파일을 클릭한 다음 열기를 가리킵니다.추적 파일이 저장된 위치로 이동합니다.

2. 열려는 추적 파일을 두 번 클릭합니다.

참고: Shift 키를 누른 상태에서 여러 개의 추적 파일을 선택하여 동시에 엽니다.서비스 추적 뷰어는 모든 파일의 내용을 병합하고 하나의 보기를 표시합니다.예를 들어 클라이언트와 서비스의 추적 파일을 모두 열 수 있습니다.이 기능은 구성에서 메시지 로깅 및 활동 전파를 사용 가능으로 설정한 경우에 유용합니다.이런 방식으로 클라이언트와 서비스 간의 메시지 교환을 검사할 수 있습니다.여러 파일을 뷰어로 끌거나 프로젝트 탭을 사용할 수도 있습니다.자세한 내용은 프로젝트 관리 섹션을 참조하십시오.

3. 열려 있는 컬렉션에 추적 파일을 추가하려면 파일을 클릭한 다음 추가를 가리킵니다.창이 열리면 추적 파일 위치로 이동하여 추가할 파일을 두 번 클릭합니다.

또한 로그 파일 필터링과 관련하여 다음 링크가 매우 유용하다는 것을 참조하십시오.

http://msdn.microsoft.com/en-us/library/ms751526.aspx

주어진 추적 수준에서 모든 WPF 추적을 활성화하는 순수한 프로그래밍 방식을 찾고 있는 저를 위한 코드가 있습니다.참고로, 이 문서는 다음 기사를 기반으로 합니다.WPF의 소스를 추적합니다.

app.config 파일을 변경할 필요가 없으며 레지스트리도 변경할 필요가 없습니다.

이것이 제가 어떤 스타트업 장소(앱 등)에서 사용하는 방법입니다.

....
#if DEBUG
    WpfUtilities.SetTracing();
#endif
....

다음은 유틸리티 코드입니다(기본적으로 모든 경고를 기본 추적 수신기로 보냅니다).

public static void SetTracing()
{
    SetTracing(SourceLevels.Warning, null);
}

public static void SetTracing(SourceLevels levels, TraceListener listener)
{
    if (listener == null)
    {
        listener = new DefaultTraceListener();
    }

    // enable WPF tracing
    PresentationTraceSources.Refresh();

    // enable all WPF Trace sources (change this if you only want DataBindingSource)
    foreach (PropertyInfo pi in typeof(PresentationTraceSources).GetProperties(BindingFlags.Static | BindingFlags.Public))
    {
        if (typeof(TraceSource).IsAssignableFrom(pi.PropertyType))
        {
            TraceSource ts = (TraceSource)pi.GetValue(null, null);
            ts.Listeners.Add(listener);
            ts.Switch.Level = levels;
        }
    }
}

2021년의 나의 제안:

가장 좋은 방법은 사용하는 것입니다.Benoit BlanchonNuget의 작은 도서관

그의 원래 게시물은 https://stackoverflow.com/a/19610384/6296708 입니다.

GitHub 링크 및 GitHub 사용 방법에 대한 자세한 정보 + Nuget 명령: https://github.com/bblanchon/WpfBindingErrors

기능(지금까지!):

  • 바인딩 오류에 대한 예외 던지기(+ 줄 번호)
  • sourceVariable이 예외를 던지면 이 라이브러리가 예외를 포착하여 표시합니다.
  • 유닛 테스트도 지원합니다!

해피 코딩!

언급URL : https://stackoverflow.com/questions/337023/how-to-detect-broken-wpf-data-binding

반응형