내 MVVM 양식의 콤보 상자에서 현재 선택한 항목과 현재의 드롭 다운 목록 항목을 모두 표시하는 선택 상자를 새로 고치고 싶습니다. 바운드 데이터가 변경되자 마자 선택된 항목. 나는이 일이 일어날 수 없습니다. 사진을 새로 고치는 것도 중요합니다.WPF가 콤보 상자 선택 상자 및 드롭 다운 목록 항목을 동기화하지 않고 즉시 새로 고치지 않음을 알립니다.
예제 양식에는 미리로드 된 사람을 보여주는 2 개의 콤보 상자와 사람을 추가하는 단추와 기존 사람의 일부 데이터를 변경하는 단추가 있습니다. 이 버튼을 클릭하면 Person.Type
필드가 조금씩 임의로 변경되고 다른 그림 파일 문자열은 Person.PicFullPath
에 저장됩니다.
<Window x:Class="combobox_test__01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:combobox_test__01"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="420" WindowStartupLocation="CenterScreen">
<Window.Resources>
<local:VM x:Key="vm" />
<DataTemplate x:Key="cboTemplate" >
<StackPanel Orientation="Horizontal">
<Border Height="80" Width="80" >
<Image>
<Image.Source>
<PriorityBinding>
<Binding Path="PicFullPath" Mode="TwoWay"/>
</PriorityBinding>
</Image.Source>
</Image>
</Border>
<Canvas Height="80" Width="160" >
<StackPanel>
<TextBlock HorizontalAlignment="Left" Height="16" Text="{Binding Path=Name, Mode=TwoWay}" />
<TextBlock HorizontalAlignment="Left" Height="16" Text="{Binding Path=Type, Mode=TwoWay}" />
</StackPanel>
</Canvas>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<Binding Source="{StaticResource vm}" />
</Window.DataContext>
<Grid>
<ComboBox Name="cbo1" IsSynchronizedWithCurrentItem="True" HorizontalAlignment="Left" Margin="19,11,0,0" VerticalAlignment="Top" Width="159"
ItemsSource="{Binding People}"
SelectedItem="{Binding SelectedPerson}"
DisplayMemberPath="Type" />
<Button Content="New Row" HorizontalAlignment="Left" Margin="224,11,0,0" VerticalAlignment="Top" Width="142"
Command="{Binding NewRowCommand}" />
<Button Content="Change current row data" HorizontalAlignment="Left" Margin="224,48,0,0" VerticalAlignment="Top" Width="142"
Command="{Binding AlterRowCommand}" />
<ComboBox Name="cbo2" IsSynchronizedWithCurrentItem="True" HorizontalAlignment="Left" Margin="19,130,0,0" VerticalAlignment="Top" Width="159" Height="82"
ItemsSource="{Binding People}"
SelectedItem="{Binding SelectedPerson}"
ItemTemplate="{StaticResource cboTemplate}" />
</Grid>
</Window>
using myAssemblies;
using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.ComponentModel;
namespace combobox_test__01
{
public class VM : INotifyPropertyChanged
{
private ObservableCollection<Person> people;
public ObservableCollection<Person> People
{
get { return people; }
set
{
people = value;
OnPropertyChanged("People");
}
}
private Person selectedPerson;
public Person SelectedPerson
{
get { return selectedPerson; }
set
{
selectedPerson = value;
OnPropertyChanged("SelectedPerson");
People = People;
}
}
private int idx = 0;
private string[,] newP;
private string DefaultPic = @"D:\Visual Studio Testing\Icons\user-icon.png",
NewPic = @"D:\Visual Studio Testing\Small size pictures\mugshot";
private Random random = new Random();
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
public VM()
{
People = new ObservableCollection<Person>()
{
new Person() {Name="Aa", Type="Taa", PicFullPath=DefaultPic},
new Person() {Name="Bb", Type="Tbb", PicFullPath=DefaultPic},
new Person() {Name="Cc", Type="Tcc", PicFullPath=DefaultPic}
};
newP = new string[4, 3] { { "Dd", "Tdd", "" }, { "Ee", "Tee", "" }, { "Ff", "Tff", "" }, { "Gg", "Tgg", "" } };
}
public ICommand AlterRowCommand => new RelayCommandBase(AlterRow);
private void AlterRow(object parameter)
{
//Make SelectedPerson.Type into a string ending with 2 randomish digits
string fmts, picChoice;
GetDifferentData(out fmts, out picChoice);
string s = SelectedPerson.Type.Substring(0,3).PadRight(5);
SelectedPerson.Type = s + fmts;
// Use those 2 randomish digits to choose a picture from existing ones
SelectedPerson.PicFullPath = NewPic + picChoice;
// Force both setters to execute
SelectedPerson = SelectedPerson;
}
public ICommand NewRowCommand => new RelayCommandBase(NewRow);
private void NewRow(object parameter)
{
string fmts, picChoice;
GetDifferentData(out fmts, out picChoice);
People.Add(new Person() { Name = newP[idx, 0], Type = newP[idx++, 1], PicFullPath = NewPic + picChoice });
}
private void GetDifferentData(out string fmts, out string picChoice)
{
int randomi = random.Next(1, 35);
fmts = randomi.ToString("D2");
picChoice = fmts + ".jpg";
}
}
public class Person
{
public string Name { get; set; }
public string Type { get; set; }
public string PicFullPath { get; set; }
}
}
이
는 동작입니다 :응용 프로그램을 실행 뷰 모델은 1
클릭
뷰 모델 주에 '현재 행 데이터 변경'이 국가에
2
눈에 띄는에게 변경 : 선택 상자에 변경된 Type
데이터와 다른 그림을 표시하려면
콤보 상자를 클릭하십시오. cbo1
드롭 다운 목록에 People.Type
의 변경 사항이 표시됩니다. 선택 상자에는 여전히 이전 데이터가 표시됩니다.
클릭 콤보 상자 cbo2
드롭 다운 목록에 변경 People.Type
과 다른 그림이 표시됩니다. 선택 상자에는 여전히 이전 데이터가 표시됩니다.
선택한 항목을 이동하지 않고 '현재 행 데이터 변경'을 다시 클릭하십시오.
뷰 모델의 상태는 3입니다.
눈에 띄는 변경 없음 : 드롭 다운 목록을 축소하면 양식이 초기화시와 동일하게 보입니다.
클릭 콤보 상자 cbo1
드롭 다운 목록은 여전히 People.Type
의 첫 번째 변화를 보여 주지만, People.Type
다시 변경되었습니다. 선택 상자에는 여전히 원래 데이터가 표시됩니다.
클릭 콤보 상자 cbo2
마지막으로 떨어 뜨린 후 드롭 다운 목록이 변경되지 않았습니다. 선택 상자에는 여전히 원래 데이터가 표시됩니다.
뷰 모델에서 상태가 3 가지 변경되었지만 콤보 상자의 상태 상자는 선택 상자에 표시되고 상태 2는 드롭 다운 목록에 표시됩니다. 나는 그들에게 두 곳 모두에서 주 3을 보여주기를 바랍니다.
콤보 상자 cbo1을 클릭하고 다른 항목을 선택한 다음 첫 번째 항목을 선택하십시오. 그래서 우리는 선택된 항목을 옮기고 그것을 옮겼습니다.
두 콤보 상자 모두 선택 상자
의 최신 데이터를 표시합니다. 드롭 다운 목록의 유효 기간이 만료되었습니다. 둘 다 상태 2를 표시하므로 선택을 변경하고 다시 변경하면 드롭 다운 목록에 표시된 데이터가 변경되지 않습니다.
클릭 '새 행'
뷰 모델은 주 4
눈에 띄는 변화입니다 : 예상대로 - 눈에 띄는 변화가 없을 것이다, 그래서 새로운 사람이 선택되어 있지 않습니다.
드롭 다운 목록에서 콤보 상자를
새로운 사람 표시를 클릭하지만 첫 번째 항목은 아직 없음을 클릭하면 드롭 다운 목록이 첫 번째 변경 후 변경 내용을 표시 할 것 2.
상태를 보여줍니다 - 그들은 상태 2가 표시됩니다.
선택 상자를 만들고 드롭 다운 목록에 항상 최신 데이터를 표시하려면 어떻게합니까?