커스텀 리스트에 WPF ComboBox 바인딩
Selected Item/Selected Value가 업데이트되지 않은 ComboBox가 있습니다.
Items ComboBox 는 .RAS CollectionView 뷰 뷰 뷰 뷰 뷰 뷰 뷰 뷰 뷰 뷰 뷰 뷰 모델 두 (SelectedItem
★★★★★★★★★★★★★★★★★」SelectedValue
View Model 른 、 른 view view view view view 。바인딩에 에 MessageBox를 했는데, "MessageBox"는 "MessageBox"입니다.SelectedItem
/SelectedValue
이치노
View Model 클래스는 다음과 같습니다.
public ConnectionViewModel
{
private readonly CollectionView _phonebookEntries;
private string _phonebookeEntry;
public CollectionView PhonebookEntries
{
get { return _phonebookEntries; }
}
public string PhonebookEntry
{
get { return _phonebookEntry; }
set
{
if (_phonebookEntry == value) return;
_phonebookEntry = value;
OnPropertyChanged("PhonebookEntry");
}
}
}
_phonebookEntries 컬렉션은 컨스트럭터에서 비즈니스 객체에서 초기화 중입니다.ComboBox XAML은 다음과 같습니다.
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}" />
되는 실제 때 RAS에 값이기 때문에 ComboBox는 ComboBox에 표시됩니다.VPN 접속을 확립할 때 RAS에 전달해야 하는 값이기 때문입니다.DisplayMemberPath
★★★★★★★★★★★★★★★★★」SelectedValuePath
connect 、 ConnectionViewModel 、이름 、이름 。 는 ★★★★★★★★★★★★★★★★★★★★★★」DataTemplate
에 ItemsControl
Data Context View Model data data data 。
ComboBox에는 아이템 리스트가 올바르게 표시되어 UI에서 문제없이 선택할 수 있습니다.단, 명령어 메시지박스를 표시하면 전화번호부는항목 속성에 ComboBox에서 선택한 값이 아닌 초기 값이 여전히 있습니다.다른 TextBox 인스턴스는 정상적으로 업데이트되고 MessageBox에 표시됩니다.
ComboBox의 데이터 바인딩에서 부족한 점은 무엇입니까?여러 번 찾아봤지만 내가 잘못하고 있는 건 아무것도 못 찾은 것 같아.
이것은 제가 보고 있는 행동입니다만, 제 특정의 문맥에서는 어떠한 이유로도 효과가 없습니다.
Window 윈도 뷰 모델입니다.CollectionView
Connection View Models 。MainWindowView.xaml DataContext MainWindowViewModel main main 。 WindowView에는 Main WindowView.xaml이 .ItemsControl
Connection View Models (접속 뷰 모델)DataTemplate를 사용합니다.는 TextBox ConnectionViewModel을 .Text="{Binding Path=ConnectionName}"
.
public class ConnectionViewModel : ViewModelBase
{
public string Name { get; set; }
public string Password { get; set; }
}
public class MainWindowViewModel : ViewModelBase
{
// List<ConnectionViewModel>...
public CollectionView Connections { get; set; }
}
XAML 코드 배후에 있는 것
public partial class Window1
{
public Window1()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
그러면 XAML:
<DataTemplate x:Key="listTemplate">
<Grid>
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}" />
<TextBox Text="{Binding Path=Password}" />
</Grid>
</DataTemplate>
<ItemsControl ItemsSource="{Binding Path=Connections}"
ItemTemplate="{StaticResource listTemplate}" />
텍스트 상자는 모두 올바르게 바인딩되며 데이터는 텍스트 상자와 View Model 간에 문제 없이 이동합니다.Combo Box만 작동하지 않습니다.
전화번호부에 대한 당신의 추정은 옳습니다.엔트리 클래스
하고 있는 계층을의 각 에 대해 ItemsControl
내가 보기엔 좀 바보같다.
위의 예에 따라 문제를 나타내는 테스트 구현을 다음에 나타냅니다.
XAML:
<Window x:Class="WpfApplication7.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="itemTemplate">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=Name}" Width="50" />
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}"
Width="200"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Path=Connections}"
ItemTemplate="{StaticResource itemTemplate}" />
</Grid>
</Window>
코드 이면:
namespace WpfApplication7
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
public class PhoneBookEntry
{
public string Name { get; set; }
public PhoneBookEntry(string name)
{
Name = name;
}
}
public class ConnectionViewModel : INotifyPropertyChanged
{
private string _name;
public ConnectionViewModel(string name)
{
_name = name;
IList<PhoneBookEntry> list = new List<PhoneBookEntry>
{
new PhoneBookEntry("test"),
new PhoneBookEntry("test2")
};
_phonebookEntries = new CollectionView(list);
}
private readonly CollectionView _phonebookEntries;
private string _phonebookEntry;
public CollectionView PhonebookEntries
{
get { return _phonebookEntries; }
}
public string PhonebookEntry
{
get { return _phonebookEntry; }
set
{
if (_phonebookEntry == value) return;
_phonebookEntry = value;
OnPropertyChanged("PhonebookEntry");
}
}
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged("Name");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class MainWindowViewModel
{
private readonly CollectionView _connections;
public MainWindowViewModel()
{
IList<ConnectionViewModel> connections = new List<ConnectionViewModel>
{
new ConnectionViewModel("First"),
new ConnectionViewModel("Second"),
new ConnectionViewModel("Third")
};
_connections = new CollectionView(connections);
}
public CollectionView Connections
{
get { return _connections; }
}
}
}
그 예를 실행하면 내가 말하는 행동을 알 수 있을 것이다.TextBox는 편집할 때 바인딩이 올바르게 업데이트되지만 ComboBox는 업데이트되지 않습니다.부모 View Model을 소개한 것은 매우 혼란스러운 일입니다.
저는 현재 DataContext의 자녀에게 바인드된 아이템에 해당 자녀가 DataContext로 있다고 생각하고 작업하고 있습니다.어떻게 해서든 이 문제를 해결할 수 있는 문서를 찾을 수 없습니다.
예.,
>= Main Window Model - -> Data Context = Main Window View Model
에 바인드...항목 -> 데이터 컨텍스트 -> 데이터 컨텍스트 엔트리
-> Data = 전화번호부'데이터 콘텍스트='엔트리관련지어져 있음)★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
그것이 내 추측을 더 잘 설명해 줄 수 있을지 모르겠다.
내 가정을 확인하기 위해 TextBox의 바인딩을 다음과 같이 변경합니다.
<TextBox Text="{Binding Mode=OneWay}" Width="50" />
또한 TextBox 바인딩 루트(DataContext와 비교 중)가 ConnectionViewModel 인스턴스임을 나타냅니다.
DisplayMemberPath 및 SelectedValuePath를 "Name"으로 설정했기 때문에 공용 속성 이름을 가진 클래스 PhoneBookEntry가 있을 것으로 예상됩니다.
Data Context를 Connection View Model 개체로 설정했습니까?
당신의 코드를 복사하고 약간의 수정을 가했는데, 정상적으로 동작하고 있는 것 같습니다.뷰모델 PhoneBookEntry 속성과 콤보박스의 선택된 아이템을 변경할 수 있으며 콤보박스에서 선택한 아이템을 변경할 수 있으며 뷰모델 PhoneBookEntry 속성이 올바르게 설정되어 있습니다.
XAML 콘텐츠는 다음과 같습니다.
<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<StackPanel>
<Button Click="Button_Click">asdf</Button>
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}" />
</StackPanel>
</Grid>
</Window>
내 암호는 다음과 같습니다.
namespace WpfApplication6
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
ConnectionViewModel vm = new ConnectionViewModel();
DataContext = vm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
((ConnectionViewModel)DataContext).PhonebookEntry = "test";
}
}
public class PhoneBookEntry
{
public string Name { get; set; }
public PhoneBookEntry(string name)
{
Name = name;
}
public override string ToString()
{
return Name;
}
}
public class ConnectionViewModel : INotifyPropertyChanged
{
public ConnectionViewModel()
{
IList<PhoneBookEntry> list = new List<PhoneBookEntry>();
list.Add(new PhoneBookEntry("test"));
list.Add(new PhoneBookEntry("test2"));
_phonebookEntries = new CollectionView(list);
}
private readonly CollectionView _phonebookEntries;
private string _phonebookEntry;
public CollectionView PhonebookEntries
{
get { return _phonebookEntries; }
}
public string PhonebookEntry
{
get { return _phonebookEntry; }
set
{
if (_phonebookEntry == value) return;
_phonebookEntry = value;
OnPropertyChanged("PhonebookEntry");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
편집: Geoffs의 두 번째 예는 효과가 없는 것 같습니다만, 조금 이상합니다.ConnectionViewModel의 PhonebookEntries 속성을 ReadOnlyCollection 유형으로 변경하면 콤보박스의 SelectedValue 속성의 TwoWay 바인딩이 정상적으로 동작합니다.
Collection View에 문제가 있을 수 있습니다.출력 콘솔에 경고가 표시되었습니다.
System.Windows.데이터 경고: 50 : Collection View를 직접 사용하는 것은 완전히 지원되지 않습니다.기본 기능은 일부 비효율적이지만 작동하지만 고급 기능에서는 알려진 버그가 발생할 수 있습니다.이러한 문제를 방지하려면 파생 클래스를 사용하는 것을 고려해 보십시오.
편집2(.NET 4.5):DropDownList의 내용은 DisplayMemberPath가 아닌 ToString()을 기반으로 할 수 있습니다.한편 DisplayMemberPath는 선택한 항목과 표시된 항목의 멤버만 지정합니다.
데이터를 ComboBox에 바인딩하려면
List<ComboData> ListData = new List<ComboData>();
ListData.Add(new ComboData { Id = "1", Value = "One" });
ListData.Add(new ComboData { Id = "2", Value = "Two" });
ListData.Add(new ComboData { Id = "3", Value = "Three" });
ListData.Add(new ComboData { Id = "4", Value = "Four" });
ListData.Add(new ComboData { Id = "5", Value = "Five" });
cbotest.ItemsSource = ListData;
cbotest.DisplayMemberPath = "Value";
cbotest.SelectedValuePath = "Id";
cbotest.SelectedValue = "2";
ComboData
외관:
public class ComboData
{
public int Id { get; set; }
public string Value { get; set; }
}
(주의:Id
그리고.Value
클래스 필드가 아닌 속성이어야 합니다.)
처음에는 같은 문제인 것처럼 보였지만, 알고 보니 NHibernate/WPF 호환성 문제였습니다.이 문제는 WPF가 객체의 동일성을 체크하는 방법에 의해 발생하였습니다.SelectedValue 속성 및 SelectedValuePath 속성에서 개체 ID 속성을 사용하여 작업을 수행할 수 있었습니다.
<ComboBox Name="CategoryList"
DisplayMemberPath="CategoryName"
SelectedItem="{Binding Path=CategoryParent}"
SelectedValue="{Binding Path=CategoryParent.ID}"
SelectedValuePath="ID">
Chester의 블로그 투고, WPF Combo Box - Selected를 참조하십시오.항목, SelectedValue 및 SelectedValuePath(NHibernate 포함)를 참조하십시오.
비슷한 문제가 있었는데 Selected는항목이 업데이트되지 않았습니다.
문제는 선택한 아이템이 리스트에 포함된 아이템과 동일한 인스턴스가 아니라는 것입니다.MyCustomObject에서 Equals() 메서드를 덮어쓰고 두 인스턴스의 ID를 비교하여 ComboBox에 동일한 오브젝트임을 알려야 했습니다.
public override bool Equals(object obj)
{
return this.Id == (obj as MyCustomObject).Id;
}
언급URL : https://stackoverflow.com/questions/561166/binding-a-wpf-combobox-to-a-custom-list
'programing' 카테고리의 다른 글
git에게 자기 서명 증명서를 받아들이게 하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
---|---|
쉬운 영어로 "git reset"은 무엇을 합니까? (0) | 2023.04.09 |
워크시트 데이터에 SQL과 같은 쿼리를 만드는 Excel 함수? (0) | 2023.04.09 |
Swift에서 배열에서 요소를 제거하는 방법 (0) | 2023.04.09 |
Excel로 밀리초 표시 (0) | 2023.04.09 |