如何将ListBoxItem的属性绑定到已绑定到ListBox

时间:2017-05-08 16:37:19

标签: wpf xaml templates binding listbox

我有一个Tape对象,它有一个属性符号,它是一个List,每个Symbol对象都有一个字符串属性Representation。

现在我有一个ListBox,它应该在单独的TextBoxes中显示符号中每个符号的表示。我已经使用以下XAML代码:

<Grid>
    <Grid.Resources>
        <l:TapeToTextBoxListConverter x:Key="TapeToTextBoxListConverter"/>
    </Grid.Resources>
    <ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden">
        <ListBox x:Name="listBox" KeyboardNavigation.TabNavigation="Continue" ItemsSource="{Binding Path=Tape.Symbols, Converter={StaticResource TapeToTextBoxListConverter}, Mode=TwoWay}">
            <ListBox.ItemContainerStyle>
                <Style>
                    <Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal">
                        <StackPanel.OpacityMask>
                            <LinearGradientBrush EndPoint="1, 0.5" StartPoint="0, 0.5">
                                <GradientStop Color="#00000000" Offset="0"/>
                                <GradientStop Offset="1"/>
                                <GradientStop Color="#FF727272" Offset="0.1"/>
                                <GradientStop Color="#FF727272" Offset="0.9"/>
                            </LinearGradientBrush>
                        </StackPanel.OpacityMask>
                    </StackPanel>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.Resources>
                <Style TargetType="{x:Type TextBox}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TextBox}">
                                <Grid>
                                    <Border Width="{Binding ActualWidth, ElementName=parentElementName}" MinWidth="80" Height="80" BorderBrush="Black" BorderThickness="2" CornerRadius="5" Background="#FFBFBFBF" />
                                    <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="FontFamily" Value="Arial Bold"/>
                    <Setter Property="FontSize" Value="60"/>
                    <Setter Property="TextWrapping" Value="Wrap"/>
                    <Setter Property="TextAlignment" Value="Center"/>
                    <Setter Property="VerticalContentAlignment" Value="Center"/>            
                </Style>
            </ListBox.Resources>
        </ListBox>
    </ScrollViewer>
</Grid>

和TapeToTextBoxListConverter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        List<Symbol> symbols = (List<Symbol>)value;
        List<TextBox> list = new List<TextBox>();
        list.Add(new TextBox());
        foreach (Symbol symbol in symbols)
        {
            TextBox textBox = new TextBox();
            textBox.Text = symbol.Representation;
            list.Add(textBox);
        }
        list.Add(new TextBox());
        return list;
    }

这已经有效了,在启动时我得到了这个: enter image description here

现在,当用户编辑TextBox时,我想要更新Tape对象(或者确切地说是其中的符号列表)。 我已经尝试了各种各样的

<Setter Property="Text" Value="{Binding Path=Tape.Symbols}"/>

和模板设定器中的类似东西,但没有什么影响。如果只有我在我的转换器中获得转换功能,我已经很开心,但我甚至无法让它工作。

2 个答案:

答案 0 :(得分:0)

没有转换器返回文本框列表。那是不必要的。

摆脱转换器,在视图模型中使用ObservableCollection<Symbol>代替List<Symbol>,并使用DataTemplate创建文本框而不是值转换器。一旦使用DataTemplate正确创建文本框,将它们绑定到Representation对象的DataContext属性本身就是简单的 - 这将是Symbol,因为{{1} } ItemsSource是这些的集合。

ListBox

顺便看看酷炫的UI。我喜欢不透明渐变效果。

答案 1 :(得分:-1)

首先你需要那个绑定,你还需要它:Mode =&#34; TwoWay&#34;。

在转换器中构建列表的方式是错误的。 ListBox只需要绑定(没有转换器)。

然后,您定义一个包含TextBox的ItemTemplate(它接收一个DataTemplate)。

在该TextBox上,您可以使用setter设置绑定(仅限实例本身)。只有这次你将直接绑定到Representation属性。

<ListBox.ItemTemplate>
    <DataTemplate>
       <TextBox Text="{Binding Representation, Mode=TwoWay}"/>
    </DataTemplate>
</ListBox.ItemTemplate>

此外,你不需要ScBoxViewer而不是ListBox,ListBox已经有了一个内部。