Wpf 如何从选定项值的两个列表框更新帧源?

Wpf 如何从选定项值的两个列表框更新帧源?,wpf,binding,Wpf,Binding,我希望找到一个关于如何实现我想要的功能的答案。我有两个列表框。我从XML为它们生成内容。我还用XML定义URI资源。我想了解如何通过单击任何列表框中的任何列表框项来实现导航。因此,我需要能够从两个不同的Lisbox更新Frame的Source属性。顺便说一句,它应该是多绑定的,带有一些转换器。任何想法都将受到高度赞赏 XAML: 列表框和框架: <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

我希望找到一个关于如何实现我想要的功能的答案。我有两个列表框。我从XML为它们生成内容。我还用XML定义URI资源。我想了解如何通过单击任何列表框中的任何列表框项来实现导航。因此,我需要能够从两个不同的Lisbox更新Frame的Source属性。顺便说一句,它应该是多绑定的,带有一些转换器。任何想法都将受到高度赞赏

XAML: 列表框和框架:

<Window
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" 
mc:Ignorable="d"
x:Class="TwoListboxes_2.MainWindow"
xmlns:local="clr-namespace:TwoListboxes_2"
Title="MainWindow"
Width="1000" Height="700">
<Window.Resources>
    <local:UriConverter x:Key="UriConverter" /> 
    <XmlDataProvider x:Key="PageData" Source="Data/data.xml" XPath="/Pages" />
    <DataTemplate x:Key="SublevelListboxDataTemplate">
        <Grid>
            <TextBlock Text="{Binding XPath=@name}"/>   
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="MainListBoxDataTemplate">  
            <TextBlock Text="{Binding XPath=@name}"/>   
    </DataTemplate>
</Window.Resources>
<Grid HorizontalAlignment="Left" VerticalAlignment="Top">   
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="215"/>
            <ColumnDefinition Width="1"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid >
            <ListBox x:Name="SublevelListbox" Width="80"
                     DataContext="{Binding SelectedItem, ElementName=Nav_ListBox}"
                     ItemTemplate="{DynamicResource SublevelListboxDataTemplate}" 
                     ItemsSource="{Binding XPath=./*}" 
             />
            <Border HorizontalAlignment="Left">
                <ListBox x:Name="Nav_ListBox" 
                         ItemTemplate="{DynamicResource MainListBoxDataTemplate}" 
                         ItemsSource="{Binding Source={StaticResource PageData}, XPath=page}"
                         SelectedValuePath="@UriSource"
                         SelectedIndex="0"
                />
            </Border>
        </Grid>
        <Frame Grid.Column="2" x:Name="ContentFrame" JournalOwnership="OwnsJournal" NavigationUIVisibility="Visible" 
               Source="{Binding SelectedValue, Converter={StaticResource UriConverter}, ElementName=Nav_ListBox, Mode=TwoWay}"
            />
</Grid> 

我认为这种设计需要将主列表绑定到一个列表框,将详细列表(子列表)绑定到第二个列表。结构,即您的数据模型

大师 -明细表 -所选局部视图


然后将选定的详细视图绑定到框架。

如果我理解正确,您可以正确绑定两个列表框,唯一的问题是绑定两个不同源的框架。 您的猜测是对的,您可以使用多重绑定来实现这一点。我假设第二个列表框没有默认选择

xaml中的多重绑定如下所示

<Frame Grid.Column="2" x:Name="ContentFrame" JournalOwnership="OwnsJournal" NavigationUIVisibility="Visible">
            <Frame.Source>
                <MultiBinding Converter="{StaticResource conv}">
                    <Binding Path="SelectedItem" ElementName="Nav_ListBox"/>
                    <Binding Path="SelectedItem" ElementName="SublevelListbox"/>
                </MultiBinding>
            </Frame.Source>
        </Frame>

是的,我试过了,但不起作用。可能需要在数据类中保留一个属性,通过该属性可以绑定帧源和listbox项的selectedValue

您的意思是在列表框中列出页面,选择的内容将加载到框架中?是的,在列表框中我列出页面,选择的内容应加载到框架中。每个列表框都是导航菜单。每个项目都有一个名称和与之关联的URI源。问题是,我只能将一个列表框数据绑定到帧源。一个列表框是链接的主级别,另一个列表框是子级别。它们都是粘合的。没有样品很难压缩。我相信现在我也有了类似的东西。我有一个绑定到一个Mainlistbox的主XML列表。子级别链接的节点绑定到另一个列表。我将框架的源绑定到所选项-source=“{Binding ElementName=Nav_ListBox,Path=SelectedValue,Mode=TwoWay,Converter={StaticResource UriConverter}”。但是,我无法将“ElementName”属性绑定到两个列表框。我正在寻找如何实现这种绑定的方法。感谢您编写此转换器。我有个问题。我认为这是次要的。应用程序在生成后停止工作。VS错误消息为“找不到资源'system.xml.xmlement'。什么会导致这种错误?有什么想法吗?谢谢您的帮助。我已将Path属性更改为Path=“SelectedValue”。现在可以了。但是,我使用这种向后/向前导航。现在,如果listboxitem的URI源像以前一样加载到框架中,我就无法指示listboxitem处于选定状态。这是因为我无法访问我以前使用过的UriConverter。我在上面的代码中添加了它。我想知道是否有可能将两个转换器合并为一个。我试图让它工作,但总是在一个内置的错误。请让我知道是否有可能实现。再次感谢你的帮助。我非常感谢。我还将绑定更改为,但是,它对UriConverter没有任何作用。我真的被困在这里了。使用框架导航的后退/前进按钮进行导航时,无法选择listboxitems。克服这一点的诀窍是什么。再次感谢你,谢谢你的关注。我同意你的回答。谢谢你的帮助。我还修改了您提供给我的多重绑定转换器。现在,它正在使用x:name=“Nav_listbox”来选择listboxitems,但它只更改第一个listbox的项目的选定状态。您可以在文本“UriConverter to alllow listboxitems在其URI源加载到框架中时处于选中状态”之后查看我上面问题中的这个多绑定转换器:“它更接近。是否可以使第二个列表框的内容相同?在我看来,当我们试图将frame.source绑定到listboxitem selectedvalue,反之亦然时,我很难做到这一点。主要的问题是,如果我们更新一个值,其他两个值将生效,这将对第一个值产生影响。从而形成一个循环。这是不可能打破的。这就是为什么我建议有一个dataclass ProeProperty,它将在用户每次更改3个控件中的任何一个时更新。然后这将更新另外两个控件。谢谢。我会调查的。然而,我是C#的初学者。我从来没有做过这个模型。
public class MultiBindConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        if (values[0] != null)
        {
            if (values[1] != null)
            {
                return new Uri(values[1].ToString(), UriKind.RelativeOrAbsolute);
            }
            return new Uri(values[0].ToString(), UriKind.RelativeOrAbsolute);
        }
        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        //throw new NotImplementedException();

        var uri = (Uri)value;
        var uriString = uri.OriginalString;
        if (value != null)
        {
            if (uri.OriginalString.Contains(";component/"))
            {
                uriString = uriString.Substring(uriString.IndexOf("/") + 1);
            }
        }
        return new object[] { uriString, uriString[0], uriString[1] };
    }
    #endregion IMultiValueConverter Members
} 
Thank you in advance.
<Frame Grid.Column="2" x:Name="ContentFrame" JournalOwnership="OwnsJournal" NavigationUIVisibility="Visible">
            <Frame.Source>
                <MultiBinding Converter="{StaticResource conv}">
                    <Binding Path="SelectedItem" ElementName="Nav_ListBox"/>
                    <Binding Path="SelectedItem" ElementName="SublevelListbox"/>
                </MultiBinding>
            </Frame.Source>
        </Frame>
public class MultiBindConverter : IMultiValueConverter {
        #region IMultiValueConverter Members

        public object Convert (object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            if (values[0] != null) {
                if (values[1] != null) {
                    return new Uri (values[1].ToString (), UriKind.RelativeOrAbsolute);
                }
                return new Uri (values[0].ToString (), UriKind.RelativeOrAbsolute);
            }
            return null;
        }

        public object[] ConvertBack (object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
            throw new NotImplementedException ();
        }

        #endregion IMultiValueConverter Members
    }