Combobox неправильно привязывается к SelectedItem - PullRequest
5 голосов
/ 16 февраля 2009

У меня есть два проекта. Один работает, а другой нет, однако различия между ними, я думаю, «не должны иметь» никакого значения. Первый проект - тот, который сломан, и это тот, который я пытаюсь исправить. Второй проект - это небольшой пример проекта, который я создал, когда первый проект просто не работает вообще. Конечно, образец работает отлично.

Вот вид для первого проекта. Я удалил кучу «MainWindowTabControlStyle», потому что это просто поле со списком, который сломан. Я вполне уверен, что проблема не в стиле, потому что это копирование и вставка из проекта, который работает.

<Grid> 
<TabControl Style="{DynamicResource MainWindowTabControlStyle}"> 
    <TabItem Header="Tab 1"/> 
    <TabItem Header="Tab 2"/> 
</TabControl>
</Grid> 

<Style x:Key="MainWindowTabControlStyle" TargetType="{x:Type TabControl}"> 
... 
    <ComboBox  
        HorizontalAlignment="Right"  
        VerticalAlignment="Top"  
        IsSynchronizedWithCurrentItem="True"  
        ItemsSource="{Binding Path=Subscriptions, Mode=Default}"  
        SelectedItem="{Binding Path=SelectedSubscription, Mode=OneWayToSource}"  
        ItemTemplate="{DynamicResource SubscriptionsItemTemplate}"/> 
... 
</Style> 

<DataTemplate x:Key="SubscriptionsItemTemplate"> 
    <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Path=DisplayName, Mode=Default}"/> 
    </StackPanel> 
</DataTemplate>

Вот модель представления, для которой задан DataContext MainWindow. Класс ViewModelBase - это тот же код, который Джош Смит написал в этой статье MSDN за несколько месяцев.

public sealed class MainWindowViewModel : ViewModelBase 
{ 
    public MainWindowViewModel() 
    { 
    } 

    private ObservableCollection<Subscription> subscriptions; 
    public ObservableCollection<Subscription> Subscriptions 
    { 
        get 
        { 
            if (subscriptions == null) 
            { 
                subscriptions = new ObservableCollection<Subscription>(); 
                subscriptions.Add(new Subscription() { DisplayName = "ABC" }); 
                subscriptions.Add(new Subscription() { DisplayName = "XYZ" }); 
                subscriptions.Add(new Subscription() { DisplayName = "PDQ" }); 
            } 

            return subscriptions; 
        } 
        set { subscriptions = value; } 
    } 

    private Subscription selectedSubscription; 
    public Subscription SelectedSubscription 
    { 
        get { return selectedSubscription; } 
        set { selectedSubscription = value; } 
    } 
} 

Когда я запускаю проект из отладчика, первое, что вызывается, - это метод получения коллекции подписок. Затем сеттер вызывается в SelectedSubscription (это значение равно нулю). После этого я могу изменять выбранный элемент в выпадающем списке до тех пор, пока он не станет синим на лице, и установщик свойства SelectedSubscription снова не изменится. Важно отметить, что комбинированный список содержит правильные значения.

Во втором проекте код идентичен, но первым, что вызывается, является установщик для свойства SelectedSubscription (оно равно null), затем вызывается метод получения для коллекции подписок и, наконец, вызывается установщик для SelectedSubscription время и имеет значение, соответствующее первому элементу в коллекции подписок.

Этот маленький драгоценный камень стоил мне около 5 часов, если у вас есть какие-либо идеи, я готов попробовать.

Спасибо

Ответы [ 3 ]

1 голос
/ 16 февраля 2009

Возможно изменение

SelectedItem="{Binding Path=SelectedSubscription, Mode=OneWayToSource}" 

до

SelectedItem="{Binding Path=SelectedSubscription, Mode=TwoWay}" 
0 голосов
/ 17 февраля 2009

Извините за задержку с отправкой ответа. Возникла какая-то проблема с установкой и запуском Open ID.

Это серьезно странная проблема.

Решение этой проблемы вообще не пришло из окна. До вызова метода show окна было другое окно, которое было открыто как диалог. В этом диалоге появился следующий ресурс

<Window.Resources>
    <DropShadowBitmapEffect x:Key="DropShadowEffect" Noise="0" Opacity="0.45" ShadowDepth="5" Softness="0.25"/>
</Window.Resources>

На него ссылались два текстовых блока в том же окне, что и «DynamicResource». После выключения диалога и запуска приложения с окнами, в которых возникла проблема, было обнаружено, что проблема была вызвана диалоговым окном. Пока я исследовал эту проблему, коллега предложил мне превратить DynamicResource в StaticResource, потому что не было причин для его динамичности.

Это изменение в диалоговом окне с использованием ресурса, который был доступен только в области действия диалогового окна, устранило проблему привязки, описанную выше в «Основном окне». Я думаю, что могут случиться более странные вещи.

0 голосов
/ 16 февраля 2009

Правильный способ отладки - это взять рабочий проект и поочередно (изменить его, чтобы он соответствовал неработающему коду / подтвердить, что он работает), пока он не будет идентичен неработающему проекту или не сломается. Точка, в которой он ломается, говорит вам, где проблема. Изменение поврежденного проекта обычно является безнадежным делом.

В качестве дополнительного пункта я бы рекомендовал добавить пространство имен System.Diagnostics в ваш XAML. Это приведет к появлению ошибок в окне вывода Visual Studio.

xmlns:debug="clr-namespace:System.Diagnostics;assembly=WindowsBase"

В качестве возможного связанного вопроса (в том смысле, что не совсем понятно, в чем проблема в сломанном проекте), вы могли бы взглянуть на этот вопрос StackOverflow ("Combobox, управляющий Tabcontrol"), который относится :

  • WPF,
  • ComboBoxes,
  • TabControls и
  • связывание между ними с помощью SelectedIndex.

Пока нет решения этого вопроса, но это более простая проблема.

Наконец, MSDN-код Джоша Смита довольно большой. Трудно понять, что вы изменили, добавив ComboBox, не видя весь код.

...