2012-01-10 34 views
7

Tôi muốn cập nhật các phần cụ thể của Grid theo các cách khác nhau. Hãy xem xét ví dụ về đồ chơi sau: Tôi có hai hàng: một phải được cập nhật từng cái một (a, b, c), vì các biểu tượng này phụ thuộc vào các trình kích hoạt khác nhau; hàng thứ hai phụ thuộc vào một kích hoạt duy nhất (hiển thị) cho phép hiển thị/ẩn một số dữ liệu.Chỉ định động cục bộ trong lưới

Bây giờ tôi biết rằng tôi có thể bọc toàn bộ Grid cấu thành Dynamic, và thậm chí xác định các biểu tượng để theo dõi, do đó ví dụ này làm những gì tôi muốn:

Checkbox[Dynamic[show]] 
test = {0, 0}; 
Dynamic[Grid[{{[email protected], [email protected], [email protected]}, 
    If[show, Prepend[test, "test:"], {}]}, Frame -> All], 
TrackedSymbols :> {show}] 

Mathematica graphics

Mặc dù vì lý do nào đó Tôi muốn có một số được chỉ định cục bộ Dynamic, chỉ được áp dụng cho hàng thứ hai của Grid.

Đối với những người đang tự hỏi những gì tình hình không tin kính nó sẽ là, chỉ cần tưởng tượng sau: show được sử dụng trong bất kỳ a, b hoặc c, và những Tôi không muốn để cập nhật khi show đang thay đổi, thay đổi của họ phụ thuộc vào kích hoạt khác. Tại sao không xóa sau đó show từ các biểu tượng của hàng đầu tiên? Hãy tưởng tượng, tôi không thể, vì show có mặt trong một chức năng được sử dụng trong a, b hoặc c và chức năng này tôi không thể truy cập dễ dàng.

Tất nhiên gói đối số đầu tiên của If vào Dynamic sẽ không giúp đỡ ở đây, như Grid bản thân hoặc bất kỳ của các tế bào của nó sẽ không trở thành động:

Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    If[[email protected], Prepend[test, "test:"], {}] 
    }, Frame -> All] 

Bên cạnh đó, gói liên tiếp vào Dynamic làm cho hàng đưa không hợp lệ, vì nó không có đầu List nữa:

Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    [email protected][show, Prepend[test, "test:"], {}] 
    }, Frame -> All] 

Mapping Dynamic so với hàng không hoạt động hoặc vì 01.không được cập nhật tự động:

Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    Dynamic /@ If[show, Prepend[test, "test:"], {}] 
    }, Frame -> All] 

Ngoài ra, gói Dynamic[If[...]] xung quanh các thành viên danh sách làm việc, nhưng bây giờ tôi phải đánh giá If 3 lần thay vì chỉ 1.

Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    Dynamic[If[show, #, ""]] & /@ Prepend[test, "test:"] 
    }, Frame -> All] 

có muốn biết nếu có bất kỳ giải pháp nào để khắc phục vấn đề cụ thể này bằng cách áp dụng cục bộ trình bao bọc Dynamic trên một hàng.

+0

Vì vậy, bạn cần một giải pháp trong đó 1. có một lưới với hai hàng 2. cả hai hàng phụ thuộc vào 'show' 3. nhưng chỉ hàng thứ hai phải được cập nhật khi' hiển thị 'thay đổi. Tôi đã làm đúng chứ? – Szabolcs

+0

Bạn có thể giải thích tại sao ba đánh giá của 'If' không mong muốn? Bài kiểm tra trong 'If' có đắt không? Chúng tôi có thể đưa ra một cái gì đó mà đánh giá thử nghiệm một lần duy nhất và lưu kết quả vào một biến mà sau đó điều khiển ba 'If'. Tôi tin rằng nếu bạn quấn toàn bộ điều thì bạn không thể tránh việc cập nhật 'a, b, c', nhưng tôi không chắc chắn! – Szabolcs

+0

Có, bạn đúng về các yêu cầu và không, tất nhiên thử nghiệm trong If không quá đắt, và tại thời điểm mã chạy như vậy (ánh xạ Nếu). Thậm chí còn có vấn đề hơn nữa là một thứ khác, mà tôi đang cố gắng xác định ngay bây giờ. –

Trả lời

3

Đây là một giải pháp sử dụng các thực nghiệm ValueFunction

show = True; 
test = {0, 0}; 
Checkbox[Dynamic[show]] 

Bây giờ viết ít chức năng cập nhật động của riêng bạn ở phía bên

Needs["Experimental`"]; 
row = {}; 
updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {}]; 
ValueFunction[show] = updateRow; 

Bây giờ làm cho lưới điện, và bây giờ có thể sử dụng động trên mỗi hàng , không phải trên toàn bộ Lưới, đó là những gì bạn muốn:

Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    {[email protected]} 
    }, 
Frame -> All 
] 

enter image description here

ps. Tôi chỉ đọc một bài viết ở đây bởi telefunkenvf14 đề cập đến gói này và chức năng này, mà tôi không biết, và khi tôi thấy chức năng này, tôi nhớ câu hỏi này, và tôi nghĩ rằng nó có thể sử dụng chức năng đó để giải quyết vấn đề này .

ps. Tôi cần phải làm việc thêm về cách đặt hàng lưới một cách chính xác ....

cập nhật (1)

Tôi không thể hình dung làm thế nào để ghép hàng thức trên các cột trong lưới. Đó là lạ, vì nó có đầu danh sách, nhưng nó sẽ không đi qua tất cả các cột. Nó sẽ chỉ đi vào ô đầu tiên. Cố gắng trình tự, SpanFromLeft, và như vậy, nhưng không có may mắn. Có thể ai đó có thể tìm ra phần này.

Đây là thử nghiệm hiện tại của tôi:

Needs["Experimental`"]; 
row = {}; 
updateRow[x_, v_] := row = If[v, {"test:", 0, 0}, {}]; 
ValueFunction[show] = updateRow; 
show = False; 
Checkbox[Dynamic[show]] 

f = Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    [email protected][row] 
    }, 
    Frame -> All 
    ] 

Có vẻ như nó nên được doable. Tôi không thấy vấn đề là gì bây giờ ...

cập nhật (2)

Là một giải pháp tạm thời, tôi chia hàng thứ hai bằng vũ lực trước tay. Điều này làm cho nó có thể làm những gì tôi muốn. Bạn không chắc chắn nếu điều này đáp ứng các thông số kỹ thuật OP hay không (tôi đoán là nó không), nhưng ở đây nó là:

Needs["Experimental`"]; 
ra = 0; 
rb = 0; 
rc = 0; 
updateRow[x_, v_] := 
row = If[v, ra = "test:"; rb = 0; rc = 0, ra = ""; rb = ""; rc = ""] 
ValueFunction[show] = updateRow; 
show = False; 
Checkbox[Dynamic[show]] 

f = Grid[{ 
    {[email protected], [email protected], [email protected]}, 
    {[email protected], [email protected], [email protected]} 
    }, 
    Frame -> All] 

enter image description here

+2

Tốt để xem những giờ tôi đã lãng phí trolling không gian tối tăm của tài liệu đã được đưa vào sử dụng tốt. Cảm ơn bạn đã đề cập. : D – telefunkenvf14

+0

Nasser: Không chính xác những gì tôi đang tìm kiếm, nhưng điều này độc đáo thêm vào tất cả các phương pháp tiếp cận tôi đã cố gắng cho đến nay. Vấn đề về cơ bản là cập nhật một hàng trong một Grid sao cho nội dung của hàng không bị phân chia, tách rời, nhìn vào, mổ xẻ, v.v. –

1

Đây thực sự là một lời nhận xét trên @ giải pháp Nasser và gợi ý sửa chữa để tránh phân tách thủ công của hàng thứ hai, nhưng do giới hạn về không gian trong khu vực nhận xét, tôi đăng nó dưới dạng câu trả lời. Sẽ được hạnh phúc để xóa nó ngay sau khi Nasser xác nhận rằng nó hoạt động và kết hợp nó vào câu trả lời của mình.

Các đầu mối đến một giải pháp được tìm thấy trong phần Possible Issues của Item trong tài liệu:

Nếu mục không phải là mục trên hầu hết ở trẻ em của một hàm hỗ trợ Item, nó sẽ không làm việc .

Tôi sử dụng quyền này để sửa đổi giải pháp của @ Nasser theo cách sau. Trước tiên, tôi cần phải thay đổi định nghĩa của row sao cho cả hai giá trị của show độ dài row là giống nhau.

Needs["Experimental`"]; 
row = {"", "", ""}; 
updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {"", "", ""}]; 
Experimental`ValueFunction[show] = updateRow; 

Sự thay đổi thứ hai cần thiết là để quấn mỗi phần tử của [email protected] với Item:

Grid[{{Dynam[email protected], [email protected], [email protected]}, 
{Item[[email protected][[1]]], Item[[email protected][[2]]], 
Item[[email protected][[3]]]}}, Frame -> All] 

Edit: Item wrapper là không thực sự cần thiết; nó cũng hoạt động tốt mà không có nó:

Grid[{{[email protected], [email protected], [email protected]}, 
{[email protected][[1]], [email protected][[2]], 
[email protected][[3]]}}, Frame -> All] 
+0

Vâng, tôi sẽ nói rằng hàng thứ hai vẫn được phân chia theo cách thủ công. Tôi nghĩ rằng tôi tin rằng bây giờ không có giải pháp đơn giản và rõ ràng cho vấn đề này ngoài việc gói Dynamic xung quanh toàn bộ cấu trúc Grid - hoặc chia lưới thành hai Grids và chỉ cập nhật Grid thứ hai. –

+0

@ Istvan, tôi đồng ý. IMHO giải pháp đầu tiên và cuối cùng của bạn sạch sẽ nhất. – kglr

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