2012-02-15 37 views
13

Có tiêu đề, Tôi đã thấy các cặp câu hỏi tương tự this hoặc this trong SO, nhưng tôi không thấy giải pháp cho nó.Có thể ràng buộc thuộc tính mã-đằng sau mà không cần thiết lập DataContext không?

Tôi biết nếu tôi cần phải liên kết với mã beind, tôi cần phải đặt Datacontext = this

Nhưng vấn đề của tôi là DataContext của tôi đã gắn vào ViewModel của tôi, nhưng tôi muốn làm một số thao tác giao diện người dùng bằng cách sử dụng lệnh được xác định trong mã-beind.

Có thể liên kết nó trong xaml không? Nếu vậy, làm thế nào?

EDIT: Tôi đã thử các sau:

<Window x:Class="WpfApplication3.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300" x:Name="_Root"> 
<Grid x:Name="hellogrid"> 
    <TextBlock x:Name="myTextBlock" Text="AAAA"/> 
    <Button Margin="82,119,121,120" Name="button2" Content="{Binding Path=Text, ElementName=myTextBlock}"/> 
    <Button Margin="82,72,121,0" Name="button3" Content="{Binding Path=MyText, ElementName=_Root}" Height="23" VerticalAlignment="Top" /> 
</Grid> 

Và code-behind:

public partial class Window1 : Window 
{ 
    public string MyText { get; set; } 

    public Window1() 
    { 
     InitializeComponent(); 
     MyText = "ABC"; 
    } 
} 

tôi có thể thấy Button2 lãm AAAA, nhưng Button3 cho thấy không có gì ... .

+0

Vui lòng xem câu trả lời cập nhật của tôi, tôi vừa kiểm tra và cách bạn ràng buộc nút của bạn3 Thuộc tính nội dung hoạt động tốt, bạn chỉ cần thực hiện thay đổi thông báo nếu cần thay đổi thuộc tính MyText đó tại thời điểm chạy ... –

Trả lời

14

EDIT

Giải pháp tốt nhất IMO là một posted bởi @Saad Imran trong SO question này ...

Với giải pháp này tất cả những gì bạn phải làm là đặt tên cho cửa sổ của bạn và ràng buộc với một thuộc tính trong XAML của bạn sẽ dễ dàng như thế này {Binding ElementName=MyWindowName, Path=MyText}

Vì vậy, những gì bạn đang làm với Content="{Binding Path=MyText, ElementName=_Root}" là chính xác và thuộc tính Nội dung nút của bạn được liên kết với thuộc tính MyText. tài sản để ABC MyText = "ABC"; không có thông báo thay đổi được gửi ...

cách dễ dàng để kiểm tra điều này bằng cách thiết lập thuộc tính MyText một cách rõ ràng như vậy:

private string myText = "ABC"; 
public string MyText 
{ 
    get { return myText; } 
    set { myText = value; } 
} 

hoặc đặt nó trong các nhà xây dựng trước InitializeComponent() được gọi là:

MyText = "ABC"; 
InitializeComponent(); 

Nếu bạn làm điều đó bạn sẽ nhận thấy rằng nút bấm của bạn sẽ có ABC là nội dung của nó, nhưng thay đổi để myText bất động sản sẽ không ảnh hưởng đến nội dung nút vì không có thông báo thay đổi ...

+0

Ahhh, tôi hiểu, đó là lý do tại sao tôi bị mất tích. Nó hoạt động ngay bây giờ. Cảm ơn rất nhiều! –

5

Chắc chắn, bạn có thể sử dụng ElementName:

<Window Name="root" 
     Class="..." 
     ...> 

    ... 

    <TextBox Text="{Binding Path=Foo, ElementName=root}" /> 

Bạn cũng có thể làm điều đó với RelativeSource, nhưng cú pháp là xấu xí ...

+0

Lạ, tôi đã thử cả 'ElementName' và' Binding Path = Foo, RelativeSource = {RelativeSource Self} ', nhưng cả hai đều không hoạt động. Tôi đang sử dụng WPF 3.5, có vấn đề gì không? –

+2

@KingChan, đó là vì bạn đặt thuộc tính MyText * sau * cuộc gọi đến 'InitializeComponent', vì vậy giá trị đã được truy lục trước khi bạn thay đổi nó. Vì lớp của bạn không triển khai 'INotifyPropertyChanged' và thuộc tính của bạn không phải là thuộc tính phụ thuộc, công cụ liên kết không có cách nào biết giá trị đã thay đổi, vì vậy nó không làm mới nội dung của nút. –

9

Tất nhiên

Có nhiều loại ràng buộc.Một trong những cơ bản nhất liên kết với một tài sản trên DataContext, thường được thừa hưởng từ một đối tượng phụ huynh

<DataTemplate DataType="{x:Type MyModel}"> 
    <!-- DataContext is object of type MyModel --> 
    <local:MyView /> 
</DataTemplate> 

Hoặc

<Window x:Name="MyWindow"> 
    <!-- DataContext Inherited from Window --> 
    <TextBlock Text="{Binding SomeProperty}" /> 
</Window> 

nơi

var SomeObject = new SomeModel(); 
SomeObject.SomeProperty = "Test"; 
myWindow.DataContext = SomeObject; 

loại ràng buộc khác bao gồm ElementName, nơi bạn có thể chỉ định phần tử giao diện người dùng mục tiêu để sử dụng làm nguồn dữ liệu cho ràng buộc

<StackPanel> 
    <CheckBox x:Name="SomeCheckBox" /> 
    <TextBlock Text="{Binding ElementName=SomeCheckBox, Path=IsChecked}" /> 
</StackPanel> 

hoặc

<local:MyUserControl x:Name="SomeUserControl"> 
    <Button Command="{Binding ElementName=SomeUserControl, Path=DataContext.SaveCommand}" /> 
</local:MyUserControl > 

Hoặc RelativeSource, cho phép bạn để tìm một đối tượng liên quan đến các đối tượng hiện tại để sử dụng như một DataSource

<Window Title="Test"> 
    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Title}" /> 
</Window> 

hoặc

<local:MyUserControl> 
    <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=DataContext.SaveCommand}" /> 
</local:MyUserControl > 

TemplateBinding , liên kết là lối tắt đến RelativeSource ràng buộc liên kết với một đối tượng được tạo khuôn mẫu

<Button Content="Test"> 
    <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <TextBlock Text="{TemplateBinding Content}" /> 
     </ControlTemplate> 
    </Button.Template> 
</Button> 
+0

Cảm ơn bạn đã tham khảo! Tôi đã nhận nó làm việc với RelativeSource của bạn quá. Nhưng kỳ lạ, làm thế nào đến tôi không cần INotifyPropertyChanged khi tôi sử dụng 'RelativeSource AncestorType = {x: Type Window}'? –

+1

Đây là tổng quan chung về ràng buộc trong WPF, không phải là câu trả lời cho câu hỏi của mình ... –

+0

@DeanKuga Tôi chưa rõ câu hỏi thực sự là gì trước khi mã được thêm vào và đọc nó là "Tôi có thể liên kết với một cái gì đó không mà không chỉ định nó trong DataContext ". Nó có vẻ hơi là một câu hỏi rộng, vì vậy tôi đã viết một câu trả lời rộng :) Khi mã đã được thêm vào, tôi có thể thấy rõ OP đang cố gắng làm gì, nhưng lúc đó câu trả lời đã được đăng có chứa thông tin anh cần. – Rachel

Các vấn đề liên quan