2009-02-03 28 views
7

tôi đã tạo một điều khiển người dùng trong WPF:Làm thế nào để đọc một tham số được thông qua trong một UserFrol WPF?

<UserControl x:Class="TestUserControl.Controls.GetLatest" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
     <TextBlock Name="theTextBlock"/> 
</UserControl> 

Các mã sau có một tham số gọi là "FirstMessage" mà nó đặt như nội dung của TextBlock điều khiển người dùng của tôi:

public partial class GetLatest : UserControl 
{ 
    public string FirstMessage { get; set; } 

    public GetLatest() 
    { 
     InitializeComponent(); 
     theTextBlock.Text = this.FirstMessage; 
    } 
} 

Trong mã chính của tôi Tôi có thể đặt thông số FirstMessage trong điều khiển người dùng của mình với intellisense:

<Window x:Class="TestUserControl.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" 
    xmlns:controls="clr-namespace:TestUserControl.Controls" 
    > 
    <StackPanel> 
     <controls:GetLatest FirstMessage="This is the title"/> 
    </StackPanel> 
</Window> 

Tuy nhiên, nó vẫn không đặt văn bản. Tôi đã thử Text = "{Binding Path = FirstMessage}" và các cú pháp khác mà tôi đã tìm thấy nhưng không có gì hoạt động.

Tôi làm cách nào để truy cập giá trị FirstMessage trong điều khiển người dùng của mình?

Trả lời

15

Cách tiếp cận ràng buộc của bạn không hoạt động vì thuộc tính của bạn FirstMessage không thông báo khi được cập nhật. Sử dụng thuộc tính phụ thuộc cho điều đó. Xem dưới đây:

public partial class GetLatest : UserControl 
{ 
    public static readonly DependencyProperty FirstMessageProperty = DependencyProperty.Register("FirstMessage", typeof(string), typeof(GetLatest)); 

    public string FirstMessage 
    { 
     get { return (string)GetValue(FirstMessageProperty); } 
     set { SetValue(FirstMessageProperty, value); } 
    } 

    public GetLatest() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

} 

XAML:

<UserControl x:Class="TestUserControl.Controls.GetLatest" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <TextBlock Text="{Binding FirstMessage}" /> 
</UserControl> 

Bất cứ khi nào những thay đổi sở hữu FirstMessage, khối chữ của bạn sẽ cập nhật chính nó.

+0

có! chính xác những gì tôi đang tìm kiếm, cảm ơn! –

+0

Tôi đã thử giải pháp của bạn và nhận được lỗi "Độ sâu cây logic vượt quá trong khi đi qua cây. Điều này có thể chỉ ra một chu kỳ trong cây." nhưng khi tôi loại bỏ dòng này.DataContext = này; lỗi biến mất nhưng ràng buộc sẽ không hoạt động. vấn đề ở đây là gì? –

+0

@Tri Q: Tôi cũng thấy ngoại lệ chiều sâu cây hợp lý nhưng ở mã khác. Dường như không có nhiều tài liệu liên quan đến lỗi này trên web nên tôi rất tò mò nếu bạn có thể trả lời nếu bạn đã tìm thấy giải pháp. – jpierson

3

FirstMessage được đặt sau khi hàm tạo đã được gọi. Bạn nên thay đổi Văn bản của bạn từ setter của FirstMessage.

Khi khởi tạo đối tượng từ XAML, trước tiên hàm tạo mặc định được gọi, sau đó thuộc tính được đặt trên đối tượng.

0

Trong trường hợp mã bạn đã đăng ở trên, đó là vấn đề về thời gian; thuộc tính FirstMessage không có giá trị được gán khi hàm tạo thi hành. Bạn sẽ phải thực thi mã đó trong một sự kiện xảy ra sau đó, chẳng hạn như Đã tải.

2

Ví dụ nhanh này sẽ không sử dụng bất kỳ ràng buộc nào vì giá trị không được thiết lập cho đến sau khi Trình xây dựng mặc định được gọi, nhưng dưới đây là cách bạn có thể hiển thị văn bản.

<UserControl x:Class="TestUserControl.Controls.GetLatest" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="GetLatest_Loaded"> 
     <TextBlock Name="theTextBlock"/> 
</UserControl> 

Sau đó, chỉ cần sửa đổi tập tin cs của bạn như thế này:

public partial class GetLatest : UserControl 
{ 
    public string FirstMessage { get; set; } 

    public GetLatest() 
    { 
     InitializeComponent(); 
     theTextBlock.Text = this.FirstMessage; 
    } 

    private void GetLatest_Loaded(object sender, RoutedEventArgs e) 
    { 
     theTextBlock.Text = this.FirstMessage; 
    } 
} 

Tôi khuyên bạn nên làm việc trên thiết lập một Binding thay vào đó, vì đây là một cách công bằng mã spaghetti-như thế nào.

1

Bạn cũng có thể sử dụng:

public partial class GetLatest : UserControl 
{ 
    private string _firstMessage; 
    public string FirstMessage 
    { 
     get { return _firstMessage; } 
     set { _firstMessage = value; theTextBlock.Text = value; } 
    } 

    public GetLatest() 
    { 
     InitializeComponent(); 
    } 
} 
Các vấn đề liên quan