私はWPFとDatabindingの新機能ですが、自分で解決できない奇妙な動作に遭遇しました。WPF lost Databinding
私はダイアログボックスでユーザー名付きのリストボックスとユーザー名用のテキストボックスを持っています。両方ともUserLogonLogicにバインドされています。これは、とりわけCurrentUser
プロパティを公開します。
ListBoxで名前をクリックすると、TextBoxのテキストが更新されます。また、TextBoxにユーザー名を直接入力すると、リストボックス内のSelectedItem
が更新されます。 TextBox内の部分的な名前は、リストボックス内の最初に一致する値に解決されます。存在しない場合はnullになります。
まず、ListBoxをクリックするたびにTextBoxが更新されます。デバッグは、CurrentUser
のPropertyChangeEvent
が呼び出されるたびにメソッドtxtName_TextChanged
メソッドが呼び出されることを示しています。テキストボックスに何かを入力した後で、TextBoxのDataBinding
が失われているようです。 ListBoxをクリックすると、TextBoxの更なる更新はありません。 Debugは、CurrentUser
PropertyChangeEvent
が起動された後で、メソッドtxtName_TextChanged
がもはや呼び出されていないことを示しています。
誰かが私が間違っている可能性があるアイデアはありますか?
どうもありがとう
RU
UserLogon.xaml:
<ListBox Grid.Column="0" Grid.Row="1" Grid.RowSpan="4" MinWidth="100" Margin="5" Name="lstUser" MouseUp="lstUser_MouseUp"
ItemsSource="{Binding Path=Users}" SelectedItem="{Binding Path=CurrentUser, Mode=TwoWay}"/>
<TextBox Grid.Column="1" Grid.Row="1" Margin="3" Name="txtName" TextChanged="txtName_TextChanged"
Text="{Binding Path=CurrentUser, Mode=OneWay}" />
UserLogon.xaml.cs:
public UserLogon()
{
InitializeComponent();
_logic = new UserLogonLogic();
TopLevelContainer.DataContext = _logic;
}
private int _internalChange = 0;
private void txtName_TextChanged(object sender, TextChangedEventArgs e)
{
if (_internalChange > 0)
{
return;
}
_internalChange++;
string oldName = txtName.Text;
User user = _logic.SelectByPartialUserName(oldName);
string newName = (user == null) ? "" : user.Name;
if (oldName != newName)
{
txtName.Text = (newName == "") ? oldName : newName;
txtName.Select(oldName.Length, newName.Length);
}
_internalChange--;
}
UserLogon.Logic.cs:
public class UserLogonLogic : INotifyPropertyChanged
{
private User _currentUser;
public User CurrentUser
{
get { return _currentUser; }
set
{
if (value != CurrentUser)
{
_currentUser = value;
OnPropertyChanged("CurrentUser");
}
}
private IEnumerable<User> _users;
public IEnumerable<User> Users
{
get
{
if (_users == null)
{
List<User> _users = Database.GetAllUsers();
}
return _users;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
public User SelectByPartialUserName(string value)
{
if (value != "")
{
IEnumerable<User> allUser = GetAllUserByName(value);
if (allUser.Count() > 0)
{
CurrentUser = allUser.First();
}
else
{
CurrentUser = null;
}
}
else
{
CurrentUser = null;
}
return CurrentUser;
}
private IEnumerable<User> GetAllUserByName(string name)
{
return from user in Users
where user.Name.ToLower().StartsWith(name.ToLower())
select user;
}
}
は、実際に私は、私は積極的にTextChangedのATTRIBを設定しているため、それが必要だと思ういけません。だから、私は一人ひとりのバインディングだけを使用して、CurrentUserが変更すると常に「受動的に」値を読み取るようにします。 TextBoxのアクティブな変更はすべてtxtName_TextChangedによって処理されます。 – Savinien
私はTwoWayで試してみました - 私が得た唯一の結果は、今はプログラムがうまくいっていないことです。 SelectedItemの変更は、最初からTextBoxに反映されません。 – Savinien