Как обновить источник фрейма из двух списков на значение выбранного элемента? - PullRequest
1 голос
/ 20 октября 2010

Я надеюсь найти ответ о том, как добиться функциональности, которую я пытаюсь получить.У меня есть два списка.Я генерирую контент для них из XML.Я также определяю UriSources в XML.Я хотел бы узнать, как выполнить навигацию, щелкнув любой элемент списка в любом списке.В результате мне нужно иметь возможность обновлять свойство 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> 

XML:

<?xml version="1.0" encoding="utf-8"?><Pages xmlns=""> 
    <page name="Name 1" UriSource="Pages/Name1.xaml"  /> 
    <page name="Name 2" UriSource="Pages/Name2.xaml"  > 
                    <level2 name="ALL1" UriSource="Pages/All1.xaml" /> 
            <level2 name="ALL2" UriSource="Pages/All2.xaml" /> 
                    <level2 name="ALL3" UriSource="Pages/All3.xaml" /> 
            <level2 name="ALL4" UriSource="Pages/All4.xaml" /> 
    </page> 
    <page name="Name 3" UriSource="Pages/Name3.xaml"/> 
    <page name="Name 4" UriSource="Pages/Name4.xaml" IsEnabled="True" /> 

UriConverter для всех перечисленных элементов списка, которые будут в выбранномсостояние, когда его UriSource загружен в 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();

        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.

Ответы [ 3 ]

1 голос
/ 22 октября 2010

Если я правильно понимаю, вы можете правильно связать два списка, единственная проблема - это связывание фрейма с двумя разными источниками.Ваша догадка верна, вы можете добиться этого с помощью Multibinding.Я предполагаю, что второй список не имеет выбора по умолчанию.

Мультисвязывание в 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>

Ваш конвертер будет

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
    }
1 голос
/ 20 октября 2010

Я думаю, что дизайн заключается в том, что вам нужно иметь основной список, привязанный к одному списку, список подробностей (подсписок), связанный вторым списком.Структура, т.е. ваша модель данных должна быть,

Мастера - Список деталей - Выбранный вид детализации

, и вы привязываете выбранный вид детали к кадру.

0 голосов
/ 28 октября 2010

Да, я попробовал, и это не работает. Может быть, вам нужно сохранить свойство в вашем классе данных, с помощью которого вы можете связать ваш источник фрейма и selectedValue ваших элементов списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...