2016-01-20 2 views
3

Я искал google и stackoverflow, чтобы найти ответ на мой вопрос без везения. Я нахожу решение проблемы. Пример:WPF вложенные данные привязки к управлению - почему это не работает

Data Binding to Nested Properties?

Но я уже знаю решение. Я хочу знать, ПОЧЕМУ wpf не поддерживает вложенные/пунктирные привязки данных к элементам управления.

Решение состоит в том, чтобы установить DataContext родительского элемента управления в родительский объект данных в моем случае в качестве свойства ViewModel для моего контроллера/окна datacontext. Поэтому я могу установить DataContext моей сетки, и мой код будет работать, если я изменил привязку TextBox, чтобы использовать свойство Name.

Еще одно решение заключается в том, чтобы установить значение UpdateSourceTrigger в моем текстовом поле и сохранить привязку вложенных данных к элементу управления TextBox, как показано ниже.

Но почему? Почему WPF не поддерживает вложенную привязку, как я делаю ниже, без явного определения UpdateSourceTrigger? Я хотел бы знать это :).

У меня есть этот элемент управления текстового поля:

<Window> 
    <Grid> 
     <StackPanel> 
      <Label Content="Name" FontWeight="Bold"/> 
      <TextBox x:Name="NameTextBox" Text="{Binding Path=CreateEditAssetViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Width="475" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalContentAlignment="Stretch" Margin="0, 5" /> 
     </StackPanel> 
    </Grid> 
</Window> 

Мое окно DataContext привязывается, как это:

var createEditWindow = new CreateEditWindow(); 
var createEditController = new CreateEditWindowController(); 
createEditWindow.DataContext = createEditController; 
createEditWindow.Show(); 

Мой контроллер выглядит следующим образом:

public class CreateEditWindowController : ViewModelBase, ICreateEditWindowController 
{ 
    private ICreateEditWindowViewModel _createEditWindowViewModel; 
    public ICreateEditWindowViewModel CreateEditAssetViewModel 
    { 
     get { return _createEditWindowViewModel; } 
     set 
     { 
      if (_createEditWindowViewModel == value) return; 
      _createEditWindowViewModel = value; 
      OnPropertyChanged(nameof(CreateEditAssetViewModel)); 
     } 
    } 
} 

Мой ViewModel с именем свойство, которое связывает элемент управления текстовым полем, выглядит следующим образом:

public class CreateEditWindowViewModel : ViewModelBase, ICreateEditWindowViewModel 
{ 

    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if (_name == value) return; 
      _name = value; 
      OnPropertyChanged(nameof(Name)); 
     } 
    } 
} 

И мой ViewModelBase:

public class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+0

см. Ссылку, которую вы упомянули. –

ответ

0

WPF поддерживает пунктирное свойство, но да, вы всегда должны указать свой контекст данных управления.

+0

Есть ли у вас какие-либо служебные ресурсы, объясняющие это с Microsoft? Кажется, я не могу найти :( – Poku

0

Я думаю, что wpf поддерживает вложенные/пунктирные привязки данных. Я написал ответ в указанной вами ссылке. , где

<TextBox Text="{Binding Path=MyModel.MyCounter.CurrentNumber}"/> 

связывание просто отлично работает. Не здесь, но я сделал много примеров, когда вложенные свойства должны привязываться к некоторому свойству управления. Фактически WPF должен поддерживать такой тип привязки, иначе предоставление отдельного DataContext для разделения элементов управления будет очень сложной задачей.

Некоторые примеры:

1.

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type iDP:DataRecordCellArea}},Path=Record.DataItem.IsParentRow}" Value="true"> 
<Setter Property="IsEnabled" Value="False"/> 

2.

<CheckBox HorizontalAlignment="Center" 
          VerticalAlignment="Center" 
          Cursor="Arrow" 
          IsChecked="{Binding Path=DataItem.IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type view:DeleteSubLocationsView}},Path=DataContext.ImportWizardViewModel.ContextObject.IsRQSReviewFieldChecked}"> 

example how nested binding work

1

Вот https://msdn.microsoft.com/en-us/library/ms752347%28v=vs.100%29.aspx

Посмотрите на Обеспечение визуальной обратной связи раздел, это свойство связывания Trigger, но они использовали пунктирную свойство

Same для коллекции просмотров раздел sub -> Как создать вид

Они использовали точечное свойство объекта Application.

Посмотрите на свое представление вывода, когда вы отлаживаете свой графический интерфейс, если WPF не находит свойство в контексте данных, он будет генерировать журнал!

+0

WPF находит свойство и связывает данные в свойстве с представлением, но не разрешает двухстороннюю привязку, когда я использую точечные свойства – Poku

+0

, конечно, вы можете добавить двустороннюю привязку –