Làm thế nào để thiết lập một ràng buộc trong Mã?


96

Tôi có nhu cầu thiết lập một ràng buộc trong mã.

Tôi dường như không thể hiểu nó đúng tho.

Đây là những gì tôi đã thử:

XAML:

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

Mã ẩn:

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

ViewModel:

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

Thuộc tính không cập nhật khi tôi đặt nó.

Tôi đang làm gì sai?

Câu trả lời:


193

Thay thế:

myBinding.Source = ViewModel.SomeString;

với:

myBinding.Source = ViewModel;

Thí dụ:

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);

Nguồn của bạn nên được chỉ ViewModel, các .SomeStringphần được đánh giá từ Path(các Paththể được thiết lập bởi các nhà xây dựng hoặc do Pathtài sản).


14
Bạn cũng có thể sử dụng txtText.SetBinding (TextBox.TextProperty, myBinding) ở vị trí của dòng cuối cùng chỉ để giảm gõ :)
Manish Dubey

5
@ManishDubey Lợi ích của phương thức tĩnh là tham số đầu tiên được định nghĩa là DependencyObject, vì vậy nó cho phép liên kết dữ liệu trên các đối tượng không xuất phát từ FrameworkElement hoặc FrameworkContentElement (chẳng hạn như Freezables).
FreddyFlares

Cảm ơn vì điều đó. Đấu tranh một chút để tìm kiếm một ví dụ như thế này
Jesse Roper

11

Bạn cần thay đổi nguồn thành đối tượng view model:

myBinding.Source = viewModelObject;

1

Ngoài câu trả lời của Dyppl , tôi nghĩ sẽ rất tuyệt nếu đặt nó vào bên trong OnDataContextChangedsự kiện:

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);
}

Chúng tôi cũng đã có những trường hợp chúng tôi chỉ lưu DataContextvào một thuộc tính cục bộ và sử dụng nó để truy cập các thuộc tính của viewmodel. Sự lựa chọn tất nhiên là của bạn, tôi thích cách tiếp cận này vì nó phù hợp hơn với phần còn lại. Bạn cũng có thể thêm một số xác nhận, như kiểm tra rỗng. Nếu bạn thực sự thay đổi DataContextxung quanh, tôi nghĩ sẽ rất tuyệt nếu bạn gọi:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

để xóa ràng buộc của khung nhìn cũ ( e.oldValuetrong trình xử lý sự kiện).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.