programing

WPF MVVM 콤보 상자가 선택됨항목 또는 선택한 값이 작동하지 않습니다.

lastcode 2023. 5. 22. 21:06
반응형

WPF MVVM 콤보 상자가 선택됨항목 또는 선택한 값이 작동하지 않습니다.

갱신하다

조금 조사한 후에.문제가 발생한 것으로 보이는 것은 Selected Value/Selected입니다.항목 원본 로드가 완료되기 전에 항목이 발생하고 있습니다.브레이크 포인트에 앉아서 몇 초만 기다리면 예상대로 작동합니다.내가 이걸 어떻게 헤쳐나갈지 모르겠어요.

업데이트 종료

콤보박스와 함께 MVVM을 사용하는 WPF에서 를 사용하는 애플리케이션이 있습니다.다음은 View 모델 예제입니다.문제는 페이지를 떠난 후 ComboBox를 다시 마이그레이션할 때 선택한 현재 값이 선택되지 않았다는 것입니다.

모델 보기

public class MyViewModel
{
     private MyObject _selectedObject;
     private Collection<Object2> _objects;
     private IModel _model;

     public MyViewModel(IModel model)
    {
         _model = model;
         _objects = _model.GetObjects();
    }

    public Collection<MyObject> Objects
    {
         get
         {
              return _objects;
         }
         private set
         {
              _objects = value;
         }
     }

     public MyObject SelectedObject
     {
          get
          {
              return _selectedObject;
          }
          set
          {
               _selectedObject = value;
          }
      }
 }

이 예에서는 MyObject에 두 가지 속성(텍스트 및 ID)이 있다고 가정합니다.콤보박스용 XAML은 다음과 같습니다.

XAML

<ComboBox Name="MyComboBox" Height="23"  Width="auto" 
    SelectedItem="{Binding Path=SelectedObject,Mode=TwoWay}" 
    ItemsSource="{Binding Objects}"
    DisplayMemberPath="Text"
    SelectedValuePath="Id">

페이지로 돌아가서 개체를 재구성할 때 어떤 방식으로 구성하든 ComboBox는 값을 선택하지 않습니다.그러나 개체가 속성의 get을 통해 올바른 개체를 반환하고 있습니다.

이것이 콤보박스와 MVVM 패턴의 작동 방식에만 문제가 있는 것인지 잘 모르겠습니다.수행 중인 텍스트 상자 바인딩이 올바르게 작동합니다.

IsSynchronizedWithCurrentItem="True"날 위해 일했다!

구현을 시도해 보셨습니까?INotifyPropertyChanged뷰 모델에서, 그리고 나서 위로 올립니다.PropertyChanged이벤트가 발생했을 때SelectedItem준비됐어요?

이 자체로도 해결되지 않으면 수동으로 문제를 제기할 수 있습니다.PropertyChanged페이지로 이동할 때 이벤트를 수행하면 WPF가 자신을 다시 그려 올바른 선택 항목을 표시하기에 충분합니다.

항목을 넣어야 합니다.선택하기 전의 소스 속성항목 속성.저는 며칠 전에 그 문제를 언급하는 블로그를 우연히 발견했습니다.

저도 비슷한 문제가 있었는데 IE를 제대로 구현하고 있는지 확인함으로써 해결되었습니다.바인딩이 발생하면 개체가 일치하는지 확인하는 중이므로 동일성 검사를 올바르게 구현해야 합니다.

이 경우 개체의 해시 ID가 다르기 때문에 선택한 항목 바인딩이 작동하지 않습니다.

한 가지 가능한 솔루션은 다음과 같습니다.

선택한 항목 ID를 기준으로 항목 원본 컬렉션에서 개체를 복구하고 선택한 항목 속성을 이 ID로 설정합니다.

예:

<ctrls:ComboBoxControlBase SelectedItem="{Binding Path=SelectedProfile, Mode=TwoWay}" ItemsSource="{Binding Path=Profiles, Mode=OneWay}" IsEditable="False" DisplayMemberPath="Name" />

ItemSource에 바인딩된 속성은 다음과 같습니다.

public ObservableCollection<Profile> Profiles
{
   get { return this.profiles; }
   private set { profiles = value; RaisePropertyChanged("Profiles"); }
}

속성이 선택됨에 바인딩됨항목:

public Profile SelectedProfile 
{
    get { return selectedProfile; }
    set
    {
        if (this.SelectedUser != null)
        {
            this.SelectedUser.Profile = value; 
            RaisePropertyChanged("SelectedProfile");  
        } 
    } 
}

복구 코드는 다음과 같습니다.

    [Command("SelectionChanged")]
    public void SelectionChanged(User selectedUser)
    {
        if (selectedUser != null)
        {
            if (selectedUser is User)
            {
                if (selectedUser.Profile != null)
                {
                    this.SelectedUser = selectedUser;
                    this.selectedProfile = this.Profiles.Where(p => p.Id == this.SelectedUser.Profile.Id).FirstOrDefault();
                    MessageBroker.Instance.NotifyColleagues("ShowItemDetails"); 
                }
            }
        }            
    }

도움이 되길 바랍니다.많은 시간을 들여 답을 찾았지만 찾을 수 없었습니다.

페이지를 때, 재현페지떠때날를이,,CollectionView와관된련과 ItemsSourceComboBox삭제됩니다.그리고 그 이유는ComboBox IsSyncronizedWithCurrent이고, " " " " 입니다.SelectedItem그리고.SelectedValue속성이 재설정됩니다.
바인딩의 내부 데이터 유형 문제인 것 같습니다.다른 사람들이 위에서 제안한 것처럼, 만약 당신이SelectedValue대신 뷰 모델의 int 속성에 바인딩하면 작동합니다.바로 가기를 사용하려면 다음을 무시해야 합니다.Equals 할 때 MyObject를 비교할 수 MyObject의 입니다.Id속성이 비교됩니다.

다른 힌트: 당신이 뷰 하고 사용한다면.SelectedValue의 경우에만 사용합니다.SelectedValuePath=IdId이라int키를 에는 자열키사는경우하용를에 .TextComboBoxSelectedValue.

나는 이전에도 이 행동을 알아차렸습니다.Selected(선택됨)인덱스 속성이 동일한 버그를 발생시키지 않습니다.View 모델을 재구성하여 선택한 항목의 인덱스를 표시하고 이에 바인딩할 수 있으면 바로 사용할 수 있습니다.

색상 목록(List<Brush>)을 표시하는 ComboBox에서 이 문제가 발생했습니다.
색상을 선택할 수 있지만 선택을 닫을 때 표시되지 않았습니다(속성이 변경되었지만!).)

콤보 상자(브러쉬)에서 선택한 유형에 대해 동등(객체 obj) 메서드를 덮어쓰는 문제가 해결되었습니다. 브러시가 밀봉되어 있기 때문에 간단하지 않습니다.그래서 브러시를 포함하고 Equals를 구현하는 클래스 EqualityBrush를 작성했습니다.

public class EqualityBrush
{
    public SolidColorBrush Brush { get; set; }

    public override bool Equals(object o)
    {
        if (o is EqualityBrush)
        {
            SolidColorBrush b = ((EqualityBrush)o).Brush;
            return b.Color.R == this.Brush.Color.R && b.Color.G == this.Brush.Color.G && b.Color.B == this.Brush.Color.B;
        }
        else
            return false;
    }
}

일반적인 브러시 클래스 대신 새로운 EqualityBrush 클래스의 목록을 사용하여 문제를 해결했습니다!

내 콤보박스 XAML은 다음과 같습니다.

<ComboBox ItemsSource="{Binding BuerkertBrushes}" SelectedItem="{Binding Brush, Mode=TwoWay}" Width="40">
    <ComboBox.Resources>
        <DataTemplate DataType="{x:Type tree:EqualityBrush}">
            <Rectangle Width="20" Height="12" Fill="{Binding Brush}"/>
        </DataTemplate>
    </ComboBox.Resources>
</ComboBox>

이제 뷰 모델의 "브러쉬"-속성이 EqualityBrush 유형이어야 합니다!

저도 같은 문제가 있었습니다.사실은.선택한 항목이 컬렉션에서 어떤 개체를 사용해야 하는지 알 수 없습니다.따라서 컬렉션의 항목을 사용하려면 선택한 항목에 대해 말해야 합니다.

public MyObject SelectedObject
 {
      get
      {
          Objects.find(x => x.id == _selectedObject.id)
          return _selectedObject;
      }
      set
      {
           _selectedObject = value;
      }
 }

이것이 도움이 되길 바랍니다.

저는 이 문제에 대해 아주 간단한 답을 가지고 있습니다.먼저 다음 코드를 View Is Synchronized에 추가합니다.CurrentItem="True" 포함.

다음에는 View Model에서 해당 Property Selected Object에 새 개체를 할당할 때마다 개인 멤버가 아닌 해당 Property에 저장해야 합니다.

뷰 모델 속성은 다음과 같아야 합니다.

    public Role SelectedObject 
    {
        get { return object; }
        set
        {
            if (value != null)
            {
                if (!object.Equals(value))
                {
                    object = value;
                    OnPropertyChanged(() => SelectedObject );
                }
            }
        }
    }

이렇게 하면 문제가 해결될 것입니다.

UserControl_Loaded 이벤트에 디스패처를 추가하여 문제를 해결했습니다.

 Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
 {
     combobox.SelectedIndex = 0;
 }));

동기화됨WithCurrent=False를 사용하면 작동합니다.

저는 이 문제로 한동안 싸우고 있었습니다.제 경우에는 항목 소스로 복합 유형(목록)을 사용하고 선택한 값으로 KeyType을 사용했습니다.로드 이벤트에서 KeyType이 null로 설정되었습니다.이로 인해 모든 것이 깨졌습니다.키가 변경될 때 하위 요소가 업데이트되지 않습니다.KeyType에 대해 제안된 값이 null이 아닌지 확인하기 위해 검사를 추가했더니 모든 것이 예상대로 작동했습니다.

    #region Property: SelectedKey
    // s.Append(string.Format("SelectedKey : {0} " + Environment.NewLine, SelectedKey.ToString()));

    private KeyType _SelectedKey = new KeyType();
    public KeyType SelectedKey
    {
        get { return _SelectedKey; }
        set
        {
            if(value != null )
                if (!_SelectedKey.Equals(value))
                {
                    _SelectedKey = value;
                    OnPropertyChanged("SelectedKey");
                }
        }
    }
    #endregion SelectedKey

의 유형SelectedValuePath그리고SelectedValue정확히 같아야 합니다.

예를 들어 다음과 같은 유형의SelectedValuePath이라Int16그리고 결합하는 속성의 유형.SelectedValue이라int그것은 작동하지 않을 것입니다.

저는 그것을 찾기 위해 몇 시간을 소비합니다. 그래서 저는 질문을 받은 지 오래된 후에 여기서 답변을 드리는 것입니다.어쩌면 저와 같은 문제를 가진 다른 불쌍한 사람이 그것을 볼 수 있을지도 모릅니다.

데이터 컨텍스트를 페이지에 적용하는 방식일 수 있습니다.WPF에서 페이지로 이동할 때마다 모든 것이 다시 초기화되고, 생성자가 호출되고, 메서드가 로드됩니다. 따라서 보기 내에서 데이터 컨텍스트를 설정할 경우 선택한 항목이 사라집니다.사용자가 선택한 항목입니다.이를 방지하려면 페이지의 KeepAlive 속성을 사용합니다.

<Page KeepAlive="True" ...>
   ...
</Page>

그러면 이미 방문한 페이지로 다시 이동할 때 로드된 이벤트만 실행됩니다.따라서 로드가 아닌 초기화(외부 또는 생성자 내)에 데이터 컨텍스트를 설정해야 합니다.

그러나 이것은 페이지의 해당 인스턴스에만 적용됩니다.해당 페이지의 새 인스턴스로 이동하면 생성자가 다시 호출됩니다.

콤보 상자.SelectionBoxItem.문자열로()

로드된 이벤트 사용:

private void cmb_Loaded(object sender, RoutedEventArgs e) {
    if (cmb.Items.Count > 0) cmb.SelectedIndex = 0;          
}

저한테는 효과가 있어요.

선택한 항목을 바인딩할 수도 있습니다.View 모델에서 속성으로 인덱싱하고 선택한 항목 조작그런 식으로 항목:

        public int SelectedIndex
        {
            get { return _selectedIndex; }
            set
            {
                _selectedIndex = value;
                OnPropertyChanged();
            }    
        }

그리고 XAML에서:

<ComboBox SelectedIndex="{Binding SelectedIndex,Mode=TwoWay}" ... >

언급URL : https://stackoverflow.com/questions/663881/wpf-mvvm-combobox-selecteditem-or-selectedvalue-not-working

반응형