Свойство привязки к зависимостям пользовательского контроля [дубликат]

Это простой шаблон регулярного выражения для филиппинских номеров мобильных телефонов:

((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

или

((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

будет соответствовать этим:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

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

Проверьте его здесь: http://refiddle.com/1ox

0
задан J4N 11 March 2015 в 09:40
поделиться

3 ответа

Основная проблема заключается в том, что вы устанавливаете свой DataContext UserControl в свой конструктор:

DataContext = this;

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

Вместо этого вы изменили бы привязку в XAML UserControl следующим образом:

<TextBox Text="{Binding SelectedFile,
                RelativeSource={RelativeSource AncestorType=UserControl}}" />

Теперь, когда вы используете свой UserControl и записываете привязка как

<userControls:FileBrowserControl SelectedFile="{Binding SelectedFile}" />

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

4
ответ дан Clemens 20 August 2018 в 17:14
поделиться
  • 1
    Спасибо, спасибо. Вы, кажется, очень хорошо знаете хорошие практики. У меня есть небольшой другой вопрос: в настоящее время этот userControl имеет всю свою логику в коде. это распространено? Потому что это не очень уважает архитектуру MVVM, которую я пытаюсь выполнить. – J4N 11 March 2015 в 12:50
  • 2
    Пользователь UserControl обычно имеет всю свою логику в своем коде, по крайней мере те части логики, которые связаны с просмотром. Однако его код не должен (сильно) модифицировать его модель представления. – Clemens 11 March 2015 в 13:07
  • 3
    Хорошо, но предположим, что у меня есть фильтр, InitialDirectory, SelectedFile, ... не могу ли я связать это с ViewModel, который содержит эти поля? – J4N 11 March 2015 в 13:14
  • 4
    Как показано в ответе, вы можете связать эти свойства, чтобы просмотреть свойства модели, в которых вы используете свой элемент управления. Однако XAML UserControl может также напрямую обращаться к свойствам модели представления в качестве источников привязки, но тогда вам, возможно, не нужно будет объявлять дополнительные свойства в UserControl. Если, например, XAML вашего элемента управления будет напрямую обращаться к свойству SelectedFile модели представления, не должно быть дополнительного свойства SelectedFile в самом элементе управления. – Clemens 11 March 2015 в 13:20

Никогда не устанавливайте DataContext UserControl внутри usercontrol:

ЭТО НЕПРАВИЛЬНО:

this.DataContext = someDataContext;

, потому что, если кто-то будет использовать ваш пользовательский контроль, его обычной практикой является установка его datacontext и это противоречит тому, что вы установили ранее

<my:SomeUserControls DataContext="{Binding SomeDataContext}" />

Какой из них будет использоваться? Ну, это зависит ...

То же самое относится к свойству Name. вы не должны указывать имя для UserControl следующим образом:

<UserControl x:Class="WpfApplication1.SomeUserControl" Name="MyUserControl1" />

, поскольку он находится в конфликте с

<my:SomeUserControls Name="SomeOtherName" />

РЕШЕНИЕ: В вашем управлении просто используйте RelativeSource Mode = FindAncestor:

<TextBox Text="{Binding SelectedFile, RelativeSource={RelativeSource AncestorType="userControls:FileBrowserControl"}" />

На ваш вопрос о том, как все эти сторонние элементы управления выполнены: они используют TemplateBinding. Но TemplateBinding можно использовать только в ControlTemplate. http://www.codeproject.com/Tips/599954/WPF-TemplateBinding-with-ControlTemplate

В usercontrol xaml представляет Content of UserControl, а не ControlTemplate /

1
ответ дан Liero 20 August 2018 в 17:14
поделиться

С помощью этого:

<userControls:FileBrowserControl SelectedFile="{Binding SelectedFile}" ...

DataContext FileBrowserControl уже настроен сам по себе, поэтому вы действительно пытаетесь связать с SelectedFile, где DataContext - это FileBrowserControl, а не родительский ViewModel.

Дайте свое имя для просмотра и используйте вместо него привязку ElementName.

SelectedFile="{Binding DataContext.SelectedFile, ElementName=element}"
1
ответ дан Mike Eason 20 August 2018 в 17:14
поделиться
  • 1
    И в моей голове я слышу звук Unreal: God like :) Большое спасибо, я не думал, что привязка в родительском объекте по-прежнему относится к DataContext для ребенка. Но я немного потерял. Как все эти сторонние библиотеки делают свой пользовательский контроль, не требуя этого ElementName? – J4N 11 March 2015 в 09:53
  • 2
    Это хороший вопрос. Я думаю, это потому, что они используют CustomControls, а не UserControls, но я не совсем уверен. Вы должны опубликовать это как новый вопрос. – Mike Eason 11 March 2015 в 10:01
  • 3
    Я определенно буду, спасибо – J4N 11 March 2015 в 10:10
  • 4
    Нет проблем :-) Вы также должны отметить вопрос как ответ, если он решил вашу проблему ;-) Спасибо. – Mike Eason 11 March 2015 в 10:11
  • 5
    Извините, я учил, что я уже это сделал – J4N 11 March 2015 в 10:12
Другие вопросы по тегам:

Похожие вопросы: