我是WPF的新手,我遇到了绑定问题。
我有3个列表框,我想绑定到一个文本框。在listbox1中,我有一个名字" John Doe",在listbox2" Brian Warner"在listbox3" Anne Brown"。
当我点击" John Doe"它显示了" John Doe"在文本框中,我可以更改他的名字,因为我在我的xaml中有这个
<TextBox x:Name="Name" Text="{Binding ElementName=listbox1, Path=SelectedItem.Name}"/>
现在我想将同一个文本框的值更改为&#34; Brian Warner&#34;当我在Listbox2中选择它时,将相同的文本框更改为&#34; Anne Brown&#34;当我在Listbox3中选择她的名字时。 我还希望能够编辑他们的名字并在列表框中更新。
我想我需要找到一种方法,每次我在列表框中选择和项目时,将绑定的ElementName从Listbox1更改为Listbox2,再更改为listbox3。
我该怎么做?我非常环保,我找不到任何如何做到这一点的例子。我希望我能提供更多代码,但我不知道从哪里开始。谢谢你的帮助。
更新
我设法通过使用
从专用文本框中的3个列表框中获取所需的值SelectionChanged="listBox_SelectionChanged"
在每个文本框的xaml中。
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
tb_firstName.Text = ((sender as ListBox).SelectedItem as Person).FirstName;
tb_lastName.Text = ((sender as ListBox).SelectedItem as Person).LastName;
tb_occupation.Text = ((sender as ListBox).SelectedItem as Person).Occupation;
tb_characteristics.Text = ((sender as ListBox).SelectedItem as Person).Characteristics;
tb_email.Text = ((sender as ListBox).SelectedItem as Person).Email;
tb_phoneNr.Text = ((sender as ListBox).SelectedItem as Person).PhoneNr;
tb_moreInfo.Text = ((sender as ListBox).SelectedItem as Person).MoreInfo;
tb_group.Text = ((sender as ListBox).SelectedItem as Person).Group;
}
但是当我尝试更改文本框中的值时,它不会在列表框中更新。我怎么能这样做?
答案 0 :(得分:0)
好吧,你可以在代码等等处理这种绑定等等。但是,我会实现更简单的解决方案:只需在相同的布局和样式(或不是)中创建3个文本框,每个文本框都绑定到特定的列表框,当你举起列表框的onItemSelected事件时,只显示相关的文本框并折叠另一个。 Vuala!没有任何可能导致麻烦的绑定处理。
答案 1 :(得分:0)
一个简单的解决方案可能是
1-定义一个保存listbox ref的变量 2-对所有三个使用OnItemSelectionChange事件 3-更新标志以指示调用哪个控制事件 4-更改每个事件的文本框值 5-在文本框中更改值时,使用标志更改列表框中的值。
将文本框与三个列表框绑定是不合逻辑的。
答案 2 :(得分:0)
如果我正确理解了这个问题,那么您有一个编辑字段(TextBox
),您希望用它来显示和编辑Name
中所选数据对象的ListBox
属性。 1}}。有多个此类ListBox
个对象,用户应该能够编辑在最近使用的ListBox
中选择的数据对象。
事实证明,这不是一件非常重要的事情。我同意Ben Cohen的回复,其中一种方法是在焦点发生变化时显示和隐藏不同的 TextBox
个实例。一个相关但不同的方法是只有一个TextBox
,并在焦点变化时更新其Binding
属性。
但它比这更复杂,因为当用户选择ListBox
中的项目时,ListBox
本身并不是获得焦点的对象。它是ListBoxItem
中的ListBox
。在XAML中访问所选的ListBoxItem
似乎并不方便。但即使你可以,还有另一个问题......
此外,您无法简单地将每个TextBox
的可见性绑定到焦点状态(或合适的代理),因为只要用户实际点击TextBox
, ListBox
/其代理失去了重点。
无论如何,有点摆弄这个问题(坦率地说,可能比我应该有的多,但是嘿......我也在这里学习新东西:)),我想出了一个代码示例,我认为正是你在这里要求的(我希望反过来你想要的:) :):
<强> XAML:强>
<Window x:Class="TestSO30283586BindOnFocus.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:TestSO30283586BindOnFocus"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="dataTemplate1" DataType="{x:Type local:A}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<local:BoolToVisibilityConverter x:Key="boolToVisibilityConverter1"/>
<Style TargetType="ListBox">
<Setter Property="ItemTemplate" Value="{StaticResource dataTemplate1}"/>
<Setter Property="Tag">
<Setter.Value>
<system:Boolean>False</system:Boolean>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ListBoxItem">
<EventSetter Event="GotFocus" Handler="listBoxItem_Focus"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="Grid.Column" Value="1"/>
<Setter Property="FontSize" Value="16"/>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ListBox x:Name="listBox1"
Grid.Row="0">
<ListBox.Items>
<local:A Name="John"/>
</ListBox.Items>
</ListBox>
<ListBox x:Name="listBox2"
Grid.Row="1">
<ListBox.Items>
<local:A Name="Jacob"/>
</ListBox.Items>
</ListBox>
<ListBox x:Name="listBox3"
Grid.Row="2">
<ListBox.Items>
<local:A Name="Jingleheimer"/>
</ListBox.Items>
</ListBox>
<TextBox Text="{Binding ElementName=listBox1, Path=SelectedItem.Name, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding ElementName=listBox1, Path=Tag, Converter={StaticResource boolToVisibilityConverter1}}"/>
<TextBox Text="{Binding ElementName=listBox2, Path=SelectedItem.Name, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding ElementName=listBox2, Path=Tag, Converter={StaticResource boolToVisibilityConverter1}}"/>
<TextBox Text="{Binding ElementName=listBox3, Path=SelectedItem.Name, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding ElementName=listBox3, Path=Tag, Converter={StaticResource boolToVisibilityConverter1}}"/>
</Grid>
</Window>
<强> C#:强>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void listBoxItem_Focus(object sender, RoutedEventArgs e)
{
ListBox[] listBoxes = { listBox1, listBox2, listBox3 };
ListBoxItem item = (ListBoxItem)sender;
ListBox listBoxParent = GetParent<ListBox>(item);
foreach (ListBox listBox in listBoxes)
{
listBox.Tag = object.ReferenceEquals(listBoxParent, listBox);
}
}
private static T GetParent<T>(DependencyObject o) where T : DependencyObject
{
while (o != null && !(o is T))
{
o = VisualTreeHelper.GetParent(o);
}
return (T)o;
}
}
class A : DependencyObject
{
public static readonly DependencyProperty NameProperty = DependencyProperty.Register(
"Name", typeof(string), typeof(A));
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
}
class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is bool))
{
return Binding.DoNothing;
}
return (bool)value ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
有一些代码隐藏处理我无法在标记中解决的问题。特别是,代码隐藏包括在ListBoxItem
获得焦点时触发的事件处理程序。发生这种情况时,事件处理程序会更新每个Tag
的{{1}}属性,以使包含ListBox
的属性设置为ListBoxItem
,而另外两个true
设置为false
。
通过这种方式,我使用Tag
属性作为IsFocused
ListBoxItem
属性的代理,允许我的TextBox
元素拥有Visibility
个Tag
元素绑定到那个属性。请注意,我只在焦点收到时才设置TextBox
。这样,即使在用户选择ListBox
元素时焦点丢失,仍然可以设置可见性。
运行此程序时,每个TextBox
仅使用一个项目进行初始化。选择项目时,它将显示在右侧的TextBox
中。当三个ListBox
元素及其项目之间的焦点发生变化时,会显示和隐藏不同的TextBox
元素,但对于用户来说,它看起来只是单个TextBox
正在更新以反映当前选择
如果您修改Name
中的文字,则链接项的ListBox
属性会像您一样更新。此更改当然会反映在Tag
。
我无法向您承诺,这是最佳方式。但它确实有效。我最大的抱怨是劫持Binding
财产。但事实是,只要您不将该财产用于其他任何事情,就可以将其用于此目的。
我实际上希望有一些真正的WPF专家来告诉我,我是一个假人,并且有更好的方法来实现这一目标。但与此同时,我希望上述内容能够充分满足您的需求。 :)
我在上面提到过,替代方案是为单个TextBox
元素更新TextBox
。我还没有显示代码,但它不会有太大的不同。当然,您只有GotFocus
个ListBox.Tag
事件处理程序而不是弄乱ListBoxItem
属性,而是检索{{1}的实际数据对象发送事件,并相应地为单个Binding
对象配置新的TextBox
对象。
这种方法可以避免使用Tag
属性,甚至可能稍微提高效率(或者可能不是......它可以采用任何一种方式)。我个人发现操作绑定的代码比上面设置属性值的代码要复杂一些。但是,由于需要走可视树以找到父ListBox
,因此该代码变得复杂。所以也许这是洗漱。
除了这些差异之外,代码仍然会以相同的方式构建。