-1

dataContext をグリッドにバインドしようとしていました (以下の xaml)

<Grid  ....    DataContext="{Binding Path=NewFormViewModel}"  > ...</Grid>

このバインディングは機能せず、NewFormViewModel のゲッターが呼び出されていないことに気付きました。

この時点で、グリッドは xaml ファイルのルート要素でした。

次に、グリッド内にキャンバスを配置し、次のようにキャンバスにバインドしました。

<Grid  ....> 
  <Canvas DataContext="{Binding Path=NewFormViewModel}">
      ....
  </Canvas>
</Grid>

データバインディングは機能しました。

次に、グリッドをキャンバスに変更して、次のようにデータバインディングを試みました。

<Canvas....    DataContext="{Binding Path=NewFormViewModel}"  > ...</Canvas>

バインディングが再び機能しなくなりました。

最終的に、キャンバス内にネストされたグリッドに落ち着きました。

   <Canvas....> 
      <Grid DataContext="{Binding Path=NewFormViewModel}">
          ....
      </Grid>
    </Canvas>

問題は、xaml のルート要素へのバインドが機能しなかったのはなぜですか?

または、Canvas/Grid をルート要素としてまったく使用せず、Page/UserControl などを使用するべきでしたか?

編集

私の論理ツリーは次のようになります。

         Window   <- Data binding to object o
           |
           *
          Frame     <-Data binding to obect o inherited
           |
           *
         Canvas/Grid <- Data binding to o.NewFormViewModel failed
           |
           *
         Canvas/Grid <- Data binding to o.NewFormViewModel Succeeds

EDIT2:

壊れた xaml:

<Canvas x:Class="WPFEditors.NewForm"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="398" Width="377"
      DataContext="{Binding Path=NewFormViewModel}"
     >
    <Grid  >
    <Label DataContext="Form Type" Height="31" HorizontalAlignment="Left" Margin="12,22,0,0" VerticalAlignment="Top" Width="92" />
    <ComboBox Margin="148,22,6,347" ItemsSource="{Binding Path=FormTypes}" />
    <Label Content="Description" Height="31" HorizontalAlignment="Left" Margin="12,58,0,0"  VerticalAlignment="Top" Width="92" />
    <Label Content="{Binding Path=Heading}" ToolTip="This is pulled from the Enum defined for FormTypes" Margin="148,59,6,309" />   
    <Label Content="Version" Height="31" HorizontalAlignment="Left" Margin="12,95,0,0"  VerticalAlignment="Top" Width="92" />
    <TextBox Text="Bind this later" Margin="148,97,6,270" Height="31" />
    <Label Content="Approval Level" Height="31" HorizontalAlignment="Left" Margin="12,132,0,0" VerticalAlignment="Top" Width="92" />
    <TextBox Height="31" Margin="148,134,6,233" Text="Bind this later" />
    <Label Content="Number of Approvals" Height="31" HorizontalAlignment="Left" Margin="12,171,0,0" VerticalAlignment="Top" Width="130" />
    <TextBox Height="31" Margin="148,173,6,194" Text="Bind this later" />
    <Label Content="Heading" Height="31" HorizontalAlignment="Left" Margin="12,210,0,0" VerticalAlignment="Top" Width="130" />
    <TextBox Height="31" Margin="148,212,6,155" Text="Bind this later" />
    <Label Content="Static Data Id" Height="31" HorizontalAlignment="Left" Margin="12,247,0,0" VerticalAlignment="Top" Width="130" />
    <TextBox Height="31" Margin="148,249,6,118" Text="Bind this later" />
    <Label Content="{Binding  Path=Errors}" Background="{Binding Path=Color}" Margin="12,325,6,6" BorderThickness="1" BorderBrush="#FF000019" />
    <Button Content="Create" Margin="83,294,202,78" />
    <Button Content="Create" Margin="181,294,104,78" />
    <Button Content="Create" Margin="279,294,6,78" />
    </Grid>
</Canvas>

上記の xaml では、次の行がバインドされます。

<Label Content="{Binding Path=Heading}" 

見出しは、このドキュメントが継承するビューモデルのプロパティ内にありますが。この時点で、次の行を期待していました。

 DataContext="{Binding Path=NewFormViewModel}"

datacontext を見出しのない NewFormViewModel に変更しました。残りのバインディングはすべて失敗します。

先頭を次のように変更すると:

<Canvas x:Class="NewForm"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="398" Width="377"

     >
    <Grid DataContext="{Binding Path=NewFormViewModel}" >

見出しへのバインディングが失敗し、残りのバインディングが機能し始めます。これは、私が最初に期待していた動作です。

この xaml は、次のファイルにネストされています。

<Window x:Class="WPFEditors.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="{Binding Path=Heading}" Height="743" Width="1177">

    <StackPanel  >
        <Menu IsMainMenu="True" >
            <MenuItem Header="New">
                <MenuItem Header="New Form" Command="{Binding Path=MenuCommand}" />
            </MenuItem>    
            <MenuItem Header="Edit Form"  ItemsSource="{Binding Path=FormsAvailable}" />
            <MenuItem Header="Edit Rules" />            
        </Menu>

        <Frame  NavigationUIVisibility="Hidden" Source="{Binding Path=CurrentPage}"
                LoadCompleted="Frame_LoadCompleted"
                DataContextChanged="Frame_DataContextChanged"
                Name="frame">
        </Frame>
    </StackPanel>

</Window>

データ コンテキストを子にコピーするイベント ハンドラは次のとおりです。

private void Frame_LoadCompleted(object sender, NavigationEventArgs e)
{
    UpdateFrameDataContext(); 
}

private void Frame_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    UpdateFrameDataContext(); 
}

private void UpdateFrameDataContext()
{
    var content = frame.Content as FrameworkElement; 
    if (content == null) 
        return; 
    content.DataContext = frame.DataContext;  
}
4

1 に答える 1

0

ルート要素の Binding は、クエリしているプロパティ (NewFormViewModel) を所有するオブジェクトを (その DataContext に) 保持するコントロール階層 (Window や UserControl など) に何かがある場合に機能するはずです。

于 2012-05-14T18:46:05.460 に答える