จะตั้งค่าการผูกใน Code ได้อย่างไร?


100

ฉันจำเป็นต้องตั้งค่าการผูกรหัส

ดูเหมือนฉันจะเข้าใจไม่ถูก

นี่คือสิ่งที่ฉันได้ลอง:

XAML:

<TextBox Name="txtText"></TextBox>

รหัสหลัง:

Binding myBinding = new Binding("SomeString");
myBinding.Source = ViewModel.SomeString;
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(txtText, TextBox.TextProperty, myBinding);

ดู

public string SomeString
    {
      get
      { 
          return someString;
      }
      set 
      { 
          someString= value;
          OnPropertyChanged("SomeString");
      }
    }

คุณสมบัติไม่ได้รับการอัปเดตเมื่อฉันตั้งค่า

ผมทำอะไรผิดหรือเปล่า?

คำตอบ:


197

แทนที่:

myBinding.Source = ViewModel.SomeString;

กับ:

myBinding.Source = ViewModel;

ตัวอย่าง:

Binding myBinding = new Binding();
myBinding.Source = ViewModel;
myBinding.Path = new PropertyPath("SomeString");
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(txtText, TextBox.TextProperty, myBinding);

แหล่งที่มาของคุณควรจะเป็นเพียงแค่ViewModelการ.SomeStringเป็นส่วนหนึ่งได้รับการประเมินจากPath(คนPathที่สามารถตั้งค่าโดยการสร้างหรือโดยPathทรัพย์สิน)


14
คุณยังสามารถใช้ txtText.SetBinding (TextBox.TextProperty, myBinding) แทนบรรทัดสุดท้ายเพื่อลดการพิมพ์ :)
Manish Dubey

6
@ManishDubey ประโยชน์ของวิธีการแบบคงที่คือพารามิเตอร์แรกถูกกำหนดให้เป็น DependencyObject ดังนั้นจึงเปิดใช้งานการเชื่อมโยงข้อมูลกับวัตถุที่ไม่ได้มาจาก FrameworkElement หรือ FrameworkContentElement (เช่น Freezables)
FreddyFlares

ขอบคุณสำหรับสิ่งนี้. ดิ้นรนเล็กน้อยเพื่อหาตัวอย่างเช่นนี้
Jesse Roper


2

นอกจากคำตอบของDypplแล้วฉันคิดว่ามันจะดีที่จะวางสิ่งนี้ไว้ในOnDataContextChangedงาน:

private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    // Unforunately we cannot bind from the viewmodel to the code behind so easily, the dependency property is not available in XAML. (for some reason).
    // To work around this, we create the binding once we get the viewmodel through the datacontext.
    var newViewModel = e.NewValue as MyViewModel;

    var executablePathBinding = new Binding
    {
        Source = newViewModel,
        Path = new PropertyPath(nameof(newViewModel.ExecutablePath))
    };

    BindingOperations.SetBinding(LayoutRoot, ExecutablePathProperty, executablePathBinding);
}

นอกจากนี้เรายังมีกรณีที่เราเพิ่งบันทึกDataContextลงในคุณสมบัติท้องถิ่นและใช้เพื่อเข้าถึงคุณสมบัติของ viewmodel แน่นอนว่าทางเลือกเป็นของคุณฉันชอบแนวทางนี้เพราะสอดคล้องกับส่วนที่เหลือมากกว่า คุณยังสามารถเพิ่มการตรวจสอบความถูกต้องได้เช่นการตรวจสอบค่าว่าง ถ้าคุณเปลี่ยนไปจริงๆDataContextฉันคิดว่ามันจะเป็นการดีที่จะโทรหา:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

เพื่อล้างการเชื่อมโยงของ viewmodel เก่า ( e.oldValueในตัวจัดการเหตุการณ์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.