2010-08-10 13 views
5

Tôi không thể tìm thấy giải pháp sạch cho vấn đề sau đây mặc dù có một số câu hỏi liên quan đến SO.Phần tử truy cập bên trong Silverlight DataTemplate

Nếu tôi có mẫu dữ liệu đang được sử dụng nhiều lần, ví dụ: TreeViewItem.HeaderTemplate, làm cách nào tôi có thể thay đổi mẫu cho chỉ một số TreeViewItems.

Ví dụ: giả sử TVI HeaderTemplate của tôi có một khối chữ và tùy thuộc vào chuỗi, tôi muốn làm cho phông chữ đậm.

tôi muốn làm một cái gì đó như thế này:

((TextBlock)myTreeView.Items.ElementAt(0).FindName("myTextBlock")).FontWeight = FontWeights.Bold; 

Có ai có một giải pháp cho việc này? -> Cảm ơn Evan

Chỉnh sửa: Có cách nào để viết hàm chung để kiểm soát dựa trên tên của nó ngay cả khi nó nằm trong mẫu dữ liệu?

LayoutRoot.FindName("myTextBlock"); sẽ hoạt động nếu myTextBlock không có trong bảng dữ liệu. Làm cách nào để viết một hàm findElementInDataTemplate(string elementName, string parentName)?

Lý do câu trả lời của Evan không phải là điều tôi đang tìm kiếm là bởi vì tôi đang phát triển sự kiểm soát. Tôi muốn nhà phát triển ứng dụng sử dụng quyền kiểm soát của mình để có thể thay đổi bất kỳ phần tử nào trong điều khiển. Nếu tôi sử dụng giải pháp của Evan, điều đó sẽ yêu cầu nhà phát triển ứng dụng có quyền truy cập vào tất cả các mẫu trong điều khiển. Có thể, nhưng không lý tưởng. Cảm ơn!

+0

Nếu bạn đã sử dụng một DataTemplate có chứa một điều khiển được gọi là "myTextBlock" nhiều lần và sau đó có một số loại của 'LayoutRoot.FindName ("myTextBlock") 'hoạt động, trong đó nhiều điều khiển được gọi là" myTextBlock "bạn sẽ muốn hoạt động đó trở lại? – AnthonyWJones

+0

@AnthonyWJones Điểm tốt, được chỉnh sửa để bao gồm thông số parentName. – NickHalden

+0

@AnthonyWJones: Thông thường hai điều khiển với tên là không thể. nếu bạn giữ hai điều khiển cùng tên trong mẫu, thì mẫu được coi là sai. – Mahantesh

Trả lời

0

phiên bản Silverlight này là gì? Và năm nào của "10 tháng 8 lúc 18:55" là bài đăng này?

trong phiên bản hiện tại của SL4 nó dường như không có mặt ở đó ..

2

Nếu bạn đang sử dụng ràng buộc dữ liệu, bạn đã thử sử dụng trình chuyển đổi ràng buộc chưa? Trong trường hợp này bạn sẽ làm một cái gì đó giống như ...

FontWeight={Binding Path=TextProperty, Converter={StaticResource BoldConverter}} 

Và bộ chuyển đổi sẽ là dọc theo dòng của ...

string myTestString = (string)value; 
if (myTestString.Contains("Bob")) 
    return FontWeights.Bold; 
return FontWeights.Normal; 

Mà làm cho nó ít gây đau đớn để thử và gốc thông qua các yếu tố để xác định vị trí cụ thể.

+0

Giải pháp tuyệt vời cho câu hỏi của tôi. Bây giờ chúng ta hãy giả vờ tôi hỏi câu hỏi tôi thực sự có nghĩa là, kiểm tra chỉnh sửa của tôi. – NickHalden

1

Phản ứng đầu tiên của tôi đối với yêu cầu đó là: bạn có thực sự chắc chắn muốn làm điều đó không? Tôi thường yêu cầu các nhà phát triển xem xét các mẫu kiểm soát hiện có đang được sử dụng. Trong trường hợp này, những gì bạn có vẻ như một điều khiển Templated dường như được bảo đảm.

Tất nhiên điều này không cung cấp sự linh hoạt bạn đang theo đuổi. Những gì bạn có vẻ được sau khi là "chén thánh" của điều khiển tùy biến, mong muốn tinh chỉnh bất kỳ chi tiết nhỏ về sự kiểm soát mà không cần phải lặp lại toàn bộ mẫu kiểm soát. Tất nhiên điều này là không thực sự có thể tuyên bố, nếu nó là tôi đã sợ cú pháp và các quy tắc ngữ nghĩa mà sẽ chi phối nó.

Có nói rằng luôn có ngoại lệ. Vì vậy, tôi sẽ trình bày một lựa chọn có thể mặc dù cảm thấy rằng bạn không nên làm điều này.

answer cung cấp phương thức mở rộng Descendents cho phép bạn liệt kê các điều khiển trên cây đối tượng. Với một thể hiện của một TreeViewItem bạn sẽ có thể tìm ra TextBlock bạn đang sau với: -

TextBlock tb = treeViewItem.Descendents() 
       .OfType<TextBlock>() 
       .Where(t => t.Name == "myTextBlock") 
       .FirstOrDefault(); 
+0

Tôi nhận được thông báo lỗi Đối tượng phụ thuộc IEnumerable không chứa định nghĩa cho TypeOf – NickHalden

+0

@JGord: Đảm bảo bạn đã bao gồm 'using System.Linq' ở đầu tệp mã. – AnthonyWJones

+0

Đã có điều đó trong đó, những cạm bẫy khác có thể? – NickHalden

4

Một cách tôi đã thực hiện điều này là để lưu trữ tất cả các mục cần thiết trong một biến bộ sưu tập lớp cấp bằng Loaded sự kiện kiểm soát.Lấy ví dụ DataTemplate này.

<DataTemplate> 
    ... 
    <TextBlock Loaded="TemplateTextBlock_Loaded" /> 
</DataTemplate> 

Sau đó, bạn sử dụng sự kiện Loaded để tải lên một số loại bộ sưu tập để sử dụng sau này.

private List<TextBlock> templateTextBlocks = new List<TextBlock>(); 

private void TemplateTextBlock_Loaded(object sender, RoutedEventArgs e) 
{ 
    TextBlock tb = sender as TextBlock; 
    if (!this.templateTextBlocks.Contains(tb)) this.templateTextBlocks.Add(tb); 
} 

Tất nhiên, nếu bạn sắp xếp và dỡ kiểm soát, điều này có thể không hoạt động tốt cho bạn.

+0

Điều này làm việc cho tôi, AnthonyWJones câu trả lời là hữu ích khi cây thị giác đã được tạo ra, nhưng điều này làm việc trước đó là tốt – hungryMind

0

cũng có thể thử này

TextBlock txtBlk = grd.FindName ("txtBlkName") như TextBlock;

nơi grd = phần tử gốc của bạn (Parent của phần tử bạn đang tìm kiếm)