0

次のように、コードビハインドでコンボボックスをバインドできます。

    private void comboBox1_Loaded(object sender, RoutedEventArgs e)
    {
        var combo = sender as ComboBox;
        App.SchedulerVM = new ScheduleViewModel();
        combo.DataContext = App.SchedulerVM;
        combo.ItemsSource = App.SchedulerVM.Frequency;
    }

これは機能します-私のコンボボックスには、SchedulerVMオブジェクトの頻度リストの項目があります。

ただし、コードビハインドではこれを実行したくありません。しかし、これまでWP7でこれを行った方法は、ここでは機能していません。上記のLoadedメソッドの最後の行をコメントアウトして、XAMLでItemsSourceを設定しようとすると、機能しません。何も表示されません。

<ComboBox Name="comboBox1" Loaded ="comboBox1_Loaded" ItemsSource="{Binding 
Frequency}" />

これも機能しません:

<ComboBox Name="comboBox1" Loaded ="comboBox1_Loaded" ItemsSource="{Binding 
App.SchedulerVM.Frequency}" />

これでもない:

<ComboBox Name="comboBox1" Loaded ="comboBox1_Loaded" ItemsSource="{Binding 
SchedulerVM.Frequency}" />

理想的には、DataContextは、このコントロールのコードビハインドで明示的に設定する必要はなく、コードビハインドで設定したLayoutRootから継承されます。しかし、それはここでのトラブルシューティングのステップ2です。

私は何が間違っているのですか?'

ありがとう!

ScheduleViewModelを編集 すると次のようになります。

namespace SchedulerUI.ViewModels
{
public class ScheduleViewModel : INotifyPropertyChanged
{
    //private properties
    private Schedule _thisSchedule; 

    //public properties
    public Schedule ThisSchedule
    {
        get { return _thisSchedule; }
        set
        {
            if (value != _thisSchedule)
            {
                NotifyPropertyChanged("ThisSchedule");
            }

            _thisSchedule = value;
        }
    }

    public List<string> Frequency = new List<string>();
    public string Test;

    //constructors
    public ScheduleViewModel()
    {
        Frequency.AddRange(new string[] { "Daily", "Weekly", "Monthly" });
        Test = "This is only a test.";
    }

    //INotifyPropertyChanged Implementation
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
}

XAML全体は次のとおりです。

<UserControl x:Class="SchedulerUI.MainPage"
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"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">

        <ComboBox Height="23" HorizontalAlignment="Left" Margin="34,41,0,0" Name="comboBox1" Loaded ="comboBox1_Loaded" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Frequency}" />
        <TextBox BorderBrush="Black"  HorizontalAlignment="Left" Margin="34,41,0,0" Width="100" Height="100" DataContext="LayoutRoot.DataContext"  Text="{Binding  Test}" /> 

</Grid>
</UserControl>

コードビハインド全体は次のとおりです。

namespace SchedulerUI
{
public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        App.SchedulerVM = new ScheduleViewModel();
        comboBox1.DataContext = App.SchedulerVM;
        List<string> testlist = App.SchedulerVM.Frequency;
        string teststring = App.SchedulerVM.Test;
    }

    private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
    {
        //App.SchedulerVM = new ScheduleViewModel();
        //var root = sender as Grid;
        //if (root != null)
        //{
        //    root.DataContext = App.SchedulerVM;
        //}
    }

    private void comboBox1_Loaded(object sender, RoutedEventArgs e)
    {
        //var combo = sender as ComboBox;
        //App.SchedulerVM = new ScheduleViewModel();
        //combo.DataContext = App.SchedulerVM;
        //combo.ItemsSource = App.SchedulerVM.Frequency;
    }
}
}
4

1 に答える 1

2

次の理由により、バインディングが機能していません。

  • 最初に実行されるように設定ItemsSourceXAML、間違った/空のバインドを試みたときDataContext
  • 次に、Loaded正しい設定を行うイベントが発生しますDataContextが、既存のバインディングは自動的に更新されません。

コードビハインドでを設定する必要がある場合DataContextは、ビューコンストラクターで設定します。

public YourView()
{
    InitializeComponent();
    combo.DataContext = App.SchedulerVM;
}

次に、次のバインディングが機能するはずです。

<ComboBox Name="comboBox1" ItemsSource="{Binding Frequency}" />

WPF / Silverlightのデータバインディングには、 パブリックプロパティが必要です。現在、ビューモデルFrequency のパブリックフィールドであり、プロパティに変更すると、すべてが機能するはずです。

private List<string> frequency = new List<string>();
public List<string> Frequency { get { return frequency; } set { frequency = value; }

そして、そこでdatabindを使用せず、を設定しただけなので、最初にロードされたイベントが機能したのはそのためですcombo.ItemsSource

于 2012-08-24T17:07:50.960 に答える