WPF双向绑定TreeView所选项 - ComboBox文本 - ContainerViewModel属性

时间:2013-09-02 07:20:00

标签: wpf mvvm binding

解决

当ProductDialogBox显示时,我想要ComboBox显示类别名称(通过转换器绑定到int CategoryId),但除非我从TreeView手动选择某个类别,否则它不会更新。解决方案是添加SelectedIndex =" 0"到ComboBox

到目前为止,任务实现如下......

ProductDialogBox.xaml

<UserControl.Resources>
        <converter:CategoryIdConverter x:Key="categoryIdConverter" />

        <HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding Path=Categories}">
            <StackPanel Orientation="Horizontal">
                <Image Source="/GSM.UI;component/Resources/Images/folder.png" Margin="1,1,3,1"/>
                <TextBlock x:Name="tb" Text="{Binding Path=Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>

        <DataTemplate x:Key="CategoryItemTemplateCollapsed">
            <TextBlock Text="{Binding Path=Name, Mode=OneWay}" 
                       DataContext="{Binding 
                           Path=DataContext.CategoryId,
                           RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},
                           Converter={StaticResource categoryIdConverter}}"/>
        </DataTemplate>

        <DataTemplate x:Key="CategoryItemTemplateExpanded">
            <TreeView ItemTemplate="{StaticResource NodeTemplate}" HorizontalAlignment="Stretch" Margin="-4 0 -4 0" Foreground="#FF3C3C3C"
                      ItemsSource="{Binding Path=ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}">
                <i:Interaction.Behaviors>
                    <b:BindableSelectedItemBehavior SelectedItem_="{Binding 
                        Path=DataContext.CategoryId, Mode=TwoWay, 
                        Converter={StaticResource categoryIdConverter}, 
                        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
                </i:Interaction.Behaviors>
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="TreeViewItem.IsExpanded" Value="True"/>
                    </Style>
                </TreeView.ItemContainerStyle>
            </TreeView>
        </DataTemplate>
    </UserControl.Resources>

<ComboBox ItemsSource="{Binding Path=Categories}" SelectedIndex="0">
            <ComboBox.ItemTemplateSelector>
                <dt:CategoryTemplateSelector/>
            </ComboBox.ItemTemplateSelector>
        </ComboBox>
</UserControl>

ProductDialogViewModel.cs

    public ProductDialogViewModel(ProductViewModel product, bool update)
    {
        if(update)
            _product = updateProduct.Product;
        else
            _product = new Product();
    }

    public int CategoryId
    {
        get { return _product.CategoryId; }
        set
        {
            if (value.Equals(_product.CategoryId))
                return;

            _product.CategoryId = value;

            base.OnPropertyChanged("CategoryId");
         }
    }

旧问题 请告知我如何通过DialogBoxViewModel显示的文字在TreeViewComboBox所选项目之间实现双向绑定? TreeView内的ComboBox显示CategoryViewModel Name属性的集合。 当用户在TreeView中选择一个类别时,ComboBox文本设置为类别名称,而DialogBoxViewModel属性CategoryId设置为Id所选CategoryVM }。 然后,当设置DialogBoxVM属性CategoryId时,TreeView所选项目已设置且ComboBox文本显示相应的类别名称

通过将ComboBox选择的值绑定到相同的属性CategoryId可以部分解决问题,但在设置CategoryId时它仍然不显示任何内容。

// ViewModel
ProductDialogBoxViewModel.cs
    int CategoryId
    ObservableCollection<CategoryViewModel> Categories;

// View
ProductDialogBoxView.xaml

    <ComboBox SelectedValue="{Binding Path=CategoryId, Converter={StaticResource categoryIdNameConverter}, Mode=OneWay}"
              DisplayMemberPath="SelectedValue.Name">
      <ComboBoxItem>
         <TreeView ItemsSource={Binding Categories} ItemTemplate={<-- displays name of category -->}>
            <interaction:Interaction.Behaviors>
               <behavior:BindableSelectedItemBehavior 
                    SelectedItem_="{Binding Path=CategoryId, 
                                            Mode=TwoWay, 
                                            Converter={StaticResource categoryNameIdConverter}}" />
            </interaction:Interaction.Behaviors>
         </TreeView>
      <ComboBoxItem>
    </ComboBox>

1 个答案:

答案 0 :(得分:0)

无法将SelectedItem的{​​{1}}设置为不在其ItemsSource中的项目。我有类似的要求在Combobox中显示树视图。我要做的是创建新的Combobox模板,您可以完全控制文本区域和组合弹出窗口。然后我将TreeView放在控件模板中的Combobox弹出窗口中,并将Text想要显示的内容绑定到TreeView所选项的选择更改上。

您可以在http://msdn.microsoft.com/en-us/library/dd334408%28v=vs.95%29.aspx找到默认的组合框模板并更改您想要的部分。

您应该在ComboBox中拥有SelectedCategory类型的媒体CategoryViewModel。然后,您可以直接将treeview的SelectedItem绑定到此属性,如ProductDialogBoxViewModel

每当树视图的选择项将改变时,您的SelectedCategory将改变,反之亦然。然后,您可以将此SelectedCategory Name绑定到创建的控件模板中的组合框的文本区域。

由于