2

У меня есть usercontrol с DependencyProperty от Answer, который прилагается к TextBox.WPF Usercontrol, TextBox PropertyChanged событие не срабатывает

Я запросил базу данных и связал ответ с usercontrol и отобразилось правильное значение.

Проблема возникает, когда я редактирую TextBox, событие PropertyChanged не запускается и, таким образом, мешает мне сохранить правильное значение обратно в базу данных. См. Ниже мой код.

UserControl:

<Grid> 
    <StackPanel> 
      <TextBlock Name="txtbQuestion" TextWrapping="Wrap" Text="Question" Foreground="Black" Margin="5" Style="{DynamicResource Label}" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Text}" ></TextBlock> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition /> 
       <ColumnDefinition Width="100" /> 
      </Grid.ColumnDefinitions> 
      <TextBox Name="txtAnswer" Margin="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" > 
       <TextBox.Style> 
        <Style> 
         <Style.Triggers> 
          <DataTrigger Binding="{Binding ElementName=cbMultiLine, Path=IsChecked}" Value="True"> 
           <Setter Property="TextBox.TextWrapping" Value="Wrap" /> 
           <Setter Property="TextBox.Height" Value="100" /> 
           <Setter Property="TextBox.AcceptsReturn" Value="True" /> 
          </DataTrigger> 
         </Style.Triggers> 
        </Style> 
       </TextBox.Style> 
      </TextBox> 
      <CheckBox Name="cbMultiLine" Content="MultiLine" Margin="5" FontFamily="Georgia" Grid.Column="1" /> 
     </Grid> 
     <Line Fill="Black" Margin="4" /> 
    </StackPanel> 
</Grid> 

Usercontrol.cs:

public partial class ConditionQuestion : UserControl 
{ 

    public static readonly DependencyProperty AnswerProperty = 
DependencyProperty.Register("Answer", typeof(string), typeof(ConditionQuestion), new UIPropertyMetadata(null, Answer_PropertyChanged)); 

    public static readonly DependencyProperty QuestionProperty = 
     DependencyProperty.Register("Question", typeof(string), typeof(ConditionQuestion), new UIPropertyMetadata(null, Question_PropertyChanged)); 

    public ConditionQuestion() 
    { 
     InitializeComponent(); 
    } 

    public string Answer 
    { 
     get { return (string)GetValue(AnswerProperty); } 
     set { SetValue(AnswerProperty, value); } 
    } 

    public string Question 
    { 
     get { return (string)GetValue(QuestionProperty); } 
     set { SetValue(QuestionProperty, value); } 
    } 

    private static void Answer_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     ((ConditionQuestion)source).txtAnswer.Text = (string)e.NewValue; 
    } 

    private static void Question_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     ((ConditionQuestion)source).txtbQuestion.Text = (string)e.NewValue; 
    } 

} 

Объявление экземпляра из UserControl:

<ListBox ItemContainerStyle="{StaticResource noSelect}" ItemsSource="{Binding Answer}" 
     Name="lbQuestions" BorderBrush="#E6E6E6" > 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <my:ConditionQuestion Question="{Binding ConditionReportFormQuestions.Question}" 
            Answer="{Binding Answer, Mode=TwoWay, 
              UpdateSourceTrigger=PropertyChanged}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Я заранее извиняюсь, я {относительно новый для WPF. Может ли кто-нибудь увидеть, с чем я могу ошибиться?

Я успешно получил привязку и обновление моих других пользовательских элементов управления (этот код является почти точной копией), но ответы на них - это ListBox выборки, где этот пользовательский контроль привязан к TextBox.

Заранее спасибо, Kohan.

+0

Извините, может быть, я совсем не такой, но я не вижу, где текстовое поле txtAnswer привязано к свойству Answer. – levanovd

+0

my: ConditionQuestion имеет свойство «Ответ», это DependencyProperty, который я создал. Когда это свойство изменяется, оно обновляет текстовое поле в usercontrol. – 4imble

+0

Но где обратная связь с текстовым полем? – levanovd

ответ

4

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

Ваш код должен выглядеть как этот

<TextBlock 
    Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type my:ConditionQuestion}}, Path=Answer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 

это связывание между текстовым полем и свойством Ответ на классе ConditionQuestion (контроль пользователей). Всякий раз, когда свойство Reply изменяется в элементе управления пользователя, текстовое поле будет обновляться, и всякий раз, когда вы меняете текст в текстовом поле, свойство Reply будет обновляться. С помощью этого кода вы можете удалить свой метод Answer_PropertyChanged, который больше не нужен. привязка позаботится об этом

+1

Работает отлично, я люблю тебя, человек. Я не совсем понимаю это на данный момент, но я буду смотреть на него более поздно, когда я получу свободное время. Еще раз спасибо, позаботьтесь. – 4imble

+0

обязательное обязательство никогда не обновлять свой пользовательский интерфейс из вашей объектной модели и никогда не обновлять вашу объектную модель из вашего пользовательского интерфейса. привязка склеивает их вместе, когда модель меняет пользовательский интерфейс, отражает изменения, когда пользовательский интерфейс изменяет модель, обновляется. как только вы поймете концепцию, вы можете проектировать свой пользовательский интерфейс и модели независимо друг от друга. –

+0

Вау, моя идея была права, но я думал, что это слишком легко для ответа, и я написал ее в комментариях)) – levanovd

Смежные вопросы