我需要一個擴展方法來遍歷我的Silverlight頁面上的所有文本框。假設我總是使用網格佈局,然後我有:遞歸silverlight元素查找器擴展方法
public static IEnumerable<UIElement> Traverse(this UIElementCollection source, Func<Grid, UIElementCollection> fnRecurse)
{
foreach (UIElement item in source)
{
yield return item;
var g = source.OfType<Grid>();
foreach (Grid itemsub in g)
{
var t = fnRecurse(itemsub);
t.Traverse(fnRecurse);
yield return itemsub;
};
}
}
現在,我可以把這個作爲這樣的:
baseLayout.Children.Traverse(x => x.Children).OfType<TextBox>().ForEach(
w =>
{
//Text Box Extension Method, clears the text
w.reset();
});
這永遠不會觸發。我相信這是OfType無法區分UI元素。
我該怎麼做?我想要展開視覺樹,然後循環瀏覽。不只是文本框,但只是得到所有我想要的。我是屈服於錯誤的地方還是經常屈服?
編輯:
目前代碼
public static IEnumerable<UIElement> Traverse(this UIElementCollection source, Func<Grid, UIElementCollection> fnRecurse)
{
foreach (UIElement item in source)
{
source.OfType<Grid>().Select(x => x.Children).ForEach(v => Traverse(v, fnRecurse));
yield return item;
}
}
和電網
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="42"/>
<RowDefinition Height="42"/>
<RowDefinition Height="45"/>
<RowDefinition Height="43"/>
<RowDefinition Height="47"/>
<RowDefinition Height="46"/>
<RowDefinition/>
<RowDefinition Height="67"/>
</Grid.RowDefinitions>
<Button x:Name="saveAddressButton" Height="24" HorizontalAlignment="Left" Margin="8,0,0,8" VerticalAlignment="Bottom" Width="135" Content="Save and Add More" Click="saveClick" Style="{StaticResource SaveButton}" Foreground="White" Grid.Row="7"/>
<Button x:Name="saveAddressButton_Copy" Height="24" HorizontalAlignment="Right" Margin="0,0,8,8" VerticalAlignment="Bottom" Width="81" Content="Clear" Click="clearClick" Style="{StaticResource SaveButton}" Foreground="White" Grid.Row="7"/>
<Grid Height="30" VerticalAlignment="Top" Margin="8,9,8,0">
<TextBlock Margin="8,0,0,0" Text="AddressLine1" FontSize="16" Foreground="White" HorizontalAlignment="Left" Width="121"/>
<TextBox x:Name="inputAddressLine1" TextWrapping="Wrap" Margin="218,0,0,0"/>
</Grid>
<Grid Height="30" Margin="8,8,8,0" VerticalAlignment="Top" Grid.Row="2">
<TextBlock Margin="8,0,0,0" Text="AddressLine2" FontSize="16" Foreground="White" HorizontalAlignment="Left" Width="146"/>
<TextBox x:Name="inputAddressLine2" TextWrapping="Wrap" Margin="219,0,0,0"/>
</Grid>
<Grid Height="30" Margin="8,0,8,7" VerticalAlignment="Bottom" Grid.Row="1">
<TextBlock Margin="8,0,0,0" Text="Post Code" FontSize="16" Foreground="White" HorizontalAlignment="Left" Width="107"/>
<TextBox x:Name="inputPostCode" TextWrapping="Wrap" Margin="219,0,0,0"/>
</Grid>
<Grid Height="30" VerticalAlignment="Bottom" Margin="8,0,8,9" Grid.Row="4">
<TextBox x:Name="inputCounty" TextWrapping="Wrap" Margin="220,0,0,0"/>
<TextBlock Margin="8,0,0,0" Text="County" FontSize="16" Foreground="White" HorizontalAlignment="Left" Width="155"/>
</Grid>
<Grid Margin="8,8,8,5" Grid.Row="3">
<TextBox x:Name="inputTown" TextWrapping="Wrap" Margin="219,0,0,0"/>
<TextBlock Margin="8,0,0,0" Text="AddressLine2" FontSize="16" Foreground="White" HorizontalAlignment="Left" Width="165"/>
</Grid>
<Grid Margin="8" Grid.Row="5">
<TextBlock Text="Number" FontSize="16" Foreground="White" Margin="8,0,0,0" HorizontalAlignment="Left" Width="178"/>
<TextBox x:Name="inputNumber" TextWrapping="Wrap" Margin="220,0,0,0"/>
</Grid>
</Grid>
仍然只獲得了這個去深一個層次上,返回6個網和一個按鈕!
我現在的導線功能是:
public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
{
source.OfType<Grid>().SelectMany(v => Traverse(v.Children));
//This is the top level.
foreach (UIElement item in source)
{
yield return item;
}
}
這只是知道我們面對的是網格所以不需要第二個參數。我只是從迭代器框中產生,而不是從第一行開始,它應該用子網格回調到Traverse函數中。
安東尼,我是一個擴展方法癮君子,因此我的ForEach!當然,這不會讓我使用收益率。 Ta代碼,我會把它,但我會避免一段時間滴答打開一個純粹的擴展方法出現! – DavidA 2010-01-26 16:29:36
你的方法有效,我的方法不行。這是一天結束......我需要知道爲什麼:) – DavidA 2010-01-26 16:45:51
@DavidA:我已經爲你添加了一個ForEach,儘管我對它的感覺如何(相信我,這真的是一個壞主意)。這將幫助我向您描述爲什麼您的原始代碼不起作用,如果a)您展示您的ForEach擴展方法和b)迭代的XAML樣本。 – AnthonyWJones 2010-01-26 16:52:20