programing

WPF - Find Name이 null을 반환하지 않아야 할 때 null을 반환합니다.

powerit 2023. 4. 19. 00:33
반응형

WPF - Find Name이 null을 반환하지 않아야 할 때 null을 반환합니다.

FindName이(가) 고장났습니다.

제가 찾는 물건은 거기에 있습니다.나는 증거를 가지고 있다.

시나리오는 다음과 같습니다.

ToggleButton button = (ToggleButton)sender;
Popup popup = (Popup)button.FindName("popSelectIteration");

popup늘은 아니지만 항상은 아닙니다. 내가 찾고 에 있다하지만 내가 찾고 있는 아이를 무효로 설정해도 거기에 있다.

무효일 때 브레이크 포인트를 넣고 이 두 개의 스크린샷을 캡처했습니다.

는 FindName이 "pop SelectIteration"에 대해 null을 반환하는 곳입니다.

하지만 시계를 들여다보면 아이가 거기에 있다는 것을 알 수 있습니다.

내가 뭘 놓쳤지?FindName에서 찾을 수 없는 이유는 무엇입니까?스크린샷에서 알 수 있듯이 이것은 타이밍의 문제가 아닙니다(FindName 워치는 null이지만 다이렉트 패스는 정상입니다).

조종 장치를 찾을 수 있는 더 좋은 방법이 있을까요?

사이드 노트:문제의 토글 버튼의 XAML에 관심이 있는 경우 다음 질문에서 찾을 수 있습니다.WPF - FrameworkElement - Enumerate all decendents?


업데이트: 이 작업이 실패하는 이유와 작동되는 이유를 조사했습니다.내가 가지고 있는 애니메이션은NameScope.SetNameScope((DependencyObject)form, new NameScope());(전체 메서드 코드는 이쪽).그 직후부터 FindName 호출이 실패합니다.

나는 그 전화를 잘 이해할 수 없다.코드를 복사해서 붙여넣은 것 같아요.아무튼 제가 댓글을 달았어요.하지만 왜 실패하는지 알고 싶어요.

시각적인 나무와 논리적인 나무의 차이와 관련이 있다고 생각합니다.컨트롤이 논리 트리에 있지만 이 컨트롤에 대한 템플릿이 아직 적용되지 않았기 때문에 FindName은 유용한 항목을 반환하지 않습니다.

먼저 컨테이너에서 ApplyTemplate();를 호출할 수 있습니다.

이것은 또한 왜 그것이 때때로 무엇인가를 반환하는지 설명해 줄 것이다.

해라

LogicalTreeHelper.FindLogicalNode(button, "popSelectIteration");

파티에는 조금 늦었지만(실제로 OP 질문에 대한 답변은 하지 않았습니다만,

수 .FindName은 꼭 RegisterName.

예:

string number = GenerateNumber();

Button myButton = new Button();
myButton.Content = number;
myButton.Name = "button_" + number;

RegisterName(myButton.Name, myButton);

Panel.Children.Add(myButton);
object o = Panel.FindName(myButton.Name);

누군가 이걸 유용하게 여길지도 몰라

제 경험상, 이것은 코드 비하인드로 아이템을 추가할 때 발생합니다.가 속일 수 FindName()(또는 애니메이션 프레임워크)를 네임 스코프로 지정합니다.할 때 됩니다.

    NameScope.GetNameScope(yourContainer).RegisterName("name of your control", yourControlInstance);

단, 이 작업을 신뢰성 있게 수행하려면 다음 이름을 등록 해제해야 합니다.

    NameScope.GetNameScope(yourContainer).UnregisterName("name of your control");

나중에 참조할 수 있도록 게시합니다.

지금은 같은 질문을 받고 있습니다만, 다음과 같은 방법을 사용하고 있습니다.

    #region Override - OnApplyTemplate

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        this.PART_ListViewLeft      = GetTemplateChild(cPART_ListViewLeft)      as ListView;
        this.PART_ListViewCenter    = GetTemplateChild(cPART_ListViewCenter)    as ListView;
        this.PART_ListViewRight     = GetTemplateChild(cPART_ListViewRight)     as ListView;

        this.PART_GridViewLeft      = GetTemplateChild(cPART_GridViewLeft)      as DsxGridView;
        this.PART_GridViewCenter    = GetTemplateChild(cPART_GridViewCenter)    as DsxGridView;
        this.PART_GridViewRight     = GetTemplateChild(cPART_GridViewRight)     as DsxGridView;
        if(this.PART_ListViewLeft!=null)
            this.PART_ListViewLeft      .AlternationCount = this.AlternatingRowBrushes.Count;
        if(this.PART_ListViewCenter!=null)
            this.PART_ListViewCenter    .AlternationCount = this.AlternatingRowBrushes.Count;
        if(this.PART_ListViewRight!=null)
            this.PART_ListViewRight     .AlternationCount = this.AlternatingRowBrushes.Count;
      //  ApplyTempleted = true;
        CreateColumnLayout();
    }
    #endregion

제어가 동적 생성이고 '가시성'이 숨기거나 접히도록 설정된 컨테이너 또는 컨테이너의 경우, 코드는this.PART_ListViewLeft = GetTemplateChild(cPART_ListViewLeft) as ListView;항상 null을 반환합니다.이유는 datatemcomplete가 이전에 아직 적용되지 않았기 때문입니다.OnApplyTemplate불리고 있다.

제 경험에 비추어 볼 때 FindName 함수는 사용하지 않는 것이 좋습니다.특히 컨트롤에 적용된 DataTemplate에서 무언가를 찾으려 할 때 문제가 됩니다.대신 가능하면 XAML에서 팝업을 선언하고 리소스처럼 참조하거나 Binding을 사용하여 모델 속성을 해당 참조로 설정합니다.행운을 빌어요.

사용해보십시오.button.FindResource("popSelectIteration")

타원스토리보드아이들.추가(myRectAnimation), containerCanvas.아이들.추가(myPath); 추가한 후 RegisterName("TextBlock1", Var_TextBox) 또는 RegisterName("myRectAnimation")과 같은 컨트롤을 등록합니다.이름, myRectAnimation);RegisterName(myPath).이름, myPath);

언급URL : https://stackoverflow.com/questions/2285491/wpf-findname-returns-null-when-it-should-not

반응형