Как привязать Combobox ItemSource к свойству, не находящемуся в DataContext?

У меня есть диалоговое окно ConfigSetup с полем со списком. Его контекст данных установлен в viewModel, но мне нужно привязать ItemSource моего Combobox к свойству в главном окне (MainWindow).

   public partial class MainWindow : Window, INotifyPropertyChanged
   {
   ...
        public CfgData.TMicMode[] MicModeOptions
        {
            get
            {
                return (CfgData.TMicMode[])System.Enum.GetValues(typeof(CfgData.TMicMode));
            }
        }

   }

Вот где viewModel настраивается в коде диалогового окна

    public partial class ConfigSetup : Window, INotifyPropertyChanged
    {
        private ConfigSetupVM vm_ = null;
        public ConfigSetup(CfgData cfgData)
        {
            vm_ = new ConfigSetupVM(cfgData);

            InitializeComponent();

            vm_.RequestClose += delegate
            {
                Close();
            };


            DataContext = vm_;

        }
   }

Вот код в виртуальной машине со свойством selectedvalue для привязки

   class ConfigSetupVM : ViewModelBase, IDataErrorInfo
    {
    ...

         /// <summary> 
        /// C-5000's microphone mode.
        /// </summary>/
        public CfgData.TMicMode MicMode
        {
            get { return model_.MicMode; }
            set { model_.MicMode = value; NotifyPropertyChanged("MicMode"); }
        }

Вот XAML с полем со списком

<Window x:Class="RpP25.ConfigSetup"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:RpWin="clr-namespace:RpP25"
    Title="FCT Configuration" 
    Width="300"
    SizeToContent="Height"
    ResizeMode="NoResize"
    WindowStartupLocation="CenterOwner" WindowStyle="ToolWindow"
    FocusManager.FocusedElement="{Binding ElementName=name}"
    Background="AliceBlue" >
    <Window.Resources>
    ...
    </Window.Resources>
    ...

    <ComboBox Grid.Row="6" Grid.Column="1"
              HorizontalAlignment="Right" MinWidth="75"
              ItemsSource="{Binding RpWin:MainWindow.MicModeOptions, Mode=OneWay}"
              SelectedValue="{Binding RpWin:MainWindow.MicMode, Mode=TwoWay, TargetNullValue=Not Selected,
                                      ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}" />


...

Я знаю, что мне не хватает чего-то фундаментального для привязки, но я не могу понять, как привязываться к чему-то вне контекста данных.

Я пытался использовать FindAncestor... безуспешно

Ваша помощь будет принята с благодарностью.


person Pat    schedule 14.07.2011    source источник


Ответы (3)


Есть два возможных пути. Первый, как показано в приведенном ниже коде, использует статический элемент.

<ComboBox ItemsSource="{Binding Source={x:Static local:MainWindow.MicModeOptions} , Mode=OneWay}"/>

public partial class MainWindow : Window, INotifyPropertyChanged
{

    public **static** CfgData.TMicMode[] MicModeOptions
    {
    }
}

Другой - использовать Resources в XAML, где целевой класс (MainWindow в вашем коде) должен получить конструктор по умолчанию (без параметров).

<Grid>
    <Grid.Resources>
        <local:MainWindow x:Key="mainWindow"/>
    </Grid.Resources>
    <ComboBox ItemsSource="{Binding Source={StaticResource mainWindow}, Path=MicModeOptions , Mode=OneWay}"/>
</Grid>
person Jin-Wook Chung    schedule 14.07.2011
comment
Спасибо. За метод 1. Почему я должен делать его статическим? Для метода 2. Создает ли новый ресурс дополнительный объект MainWindow или это ссылка на уже существующий экземпляр? - person Pat; 15.07.2011
comment
Насколько я знаю, пока нет способа связать существующий экземпляр с XAML. Итак, я упомянул static, чтобы получить ссылку на него. - person Jin-Wook Chung; 15.07.2011

Как запускается диалоговое окно? Если он запускается через window.ShowDialog(), вы можете передать необходимый объект, к которому нужно привязать, в качестве параметра конструктору вашего диалогового окна. Затем конструктор присваивает его внутреннему свойству, к которому может быть привязан ваш код XAML.

person Philipp Schmid    schedule 14.07.2011

Попробуйте этот метод, простой и чистый.

<!-- In user countrol resources -->
    <UserControl.Resources>
        <CollectionViewSource Source="{Binding Currencies}" x:Key="Currencies"/>
    </UserControl.Resources>

<!-- below inside ex. DataGrid -->
  <ComboBox ItemsSource="{Binding Source={StaticResource Currencies}}" IsSynchronizedWithCurrentItem="False"
            DisplayMemberPath="IsoCode"
            SelectedItem="{Binding BaseCurrency}"/>

<!-- IsSynchronizedWithCurrentItem="False" is important, otherwise ComboBoxes will select same item for each child viewmodel -->

ссылка на пост в блоге http://kostylizm.blogspot.ru/2014/04/wpf-combobox-itemssource-bind-to-parent.html

person Oyun    schedule 14.04.2014