如何在menuitem集合中選擇currentItem。就像人們會用列表框一樣。我試圖在collectionViewSource中包裝這個集合,然而那並沒有帶來這樣的運氣。在wpf中選擇當前MenuItem
在此先感謝。
如何在menuitem集合中選擇currentItem。就像人們會用列表框一樣。我試圖在collectionViewSource中包裝這個集合,然而那並沒有帶來這樣的運氣。在wpf中選擇當前MenuItem
在此先感謝。
如果ListBox將其ItemsSource設置爲複雜實體的通用列表,則使用ListBox.SelectedValue將獲取當前選定的數據。
例如:
public partial class NameListView : Window
{
/// <summary>
/// Constructor
/// </summary>
public NameListView()
{
List<string> names = new List<string>();
names.Add("John Doe");
names.Add("Jane Doe");
lbNameList.ItemsSource = names;
}
/// <summary>
/// Selection changed event handler for ListBox lbNameList
/// </summary>
void lbNameList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
string currentValue = lbNameList.SelectedValue.ToString();
MessageBox.Show("Currently selected value: " + currentValue);
}
}
}
的MenuBase,其文本菜單和菜單從派生,繼承ItemsControl的,其不包括的SelectedItem的概念。這是ListBox添加的內容。
但是,您確實擁有ItemsControl.ItemTemplate。這真棒。
一種選擇是讓你的ItemTemplate成爲一個ToggleButton。這給你一些事情。本質上,ToggleButtons可以看起來像使用它們的IsChecked屬性進行選擇。其次,他們有一個Command屬性,您可以綁定到ViewModel中的命令。
所以,如果你有沿着線的東西:
<Menu ItemsSource="{Binding ThingsToBindTo}">
<Menu.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.Resources>
<conv:BindingProxy x:Key="proxy" Data="{Binding}" />
</Grid.Resources>
<ToggleButton Content="{Binding NameOrLabel}" CommandParameter="{Binding}" Command="{Binding Path=DataContext.SelectThingCommand, RelativeSource={RelativeSource AncestorType=Menu}}" >
<ToggleButton.IsChecked>
<Binding Mode="OneWay" Path="DataContext.SelectedThing" RelativeSource={RelativeSource AncestorType=Menu}">
<Binding.Converter>
<conv:ComparisonConverter CompareTo="{Binding Source={StaticResource proxy}, Path=Data}" />
</Binding.Converter>
</Binding>
</ToggleButton.IsChecked>
</ToggleButton>
</Grid>
</DataTemplate>
</Menu.ItemTemplate>
</Menu>
所以這是一個有點複雜。
按照常規,您綁定到項目列表。 ThingsToBindTo應該是你的列表。然後你開始定義你的模板。 NameOrLabel是您想要在切換按鈕上顯示的任何屬性。命令參數通過使用「{綁定}」以外的任何內容綁定到模板正在包裝的數據項。該命令實際上在您的Menu的DataContext上,這就是爲什麼使用RelativeSource的原因。
這是說的是你要傳遞一個命令,那只是被點擊的東西。實際上,您正在選擇您點擊的按鈕。然後,你的命令只需要在你的ViewModel中設置一個SelectedThing屬性,它等於傳給它的任何東西。希望你已經實現了一個實現ICommand的類來創建委託命令。如果你不這樣做,那裏有很多關於如何去做的文章。如果你不知道如何,請對這篇文章發表評論,我將添加源代碼來完成它。
然後,我們有「IsChecked」壞男孩。我們實際上在那裏做了一個有約束力的約束。這是更復雜的部分,但它允許DataTemplated項目在轉換器中實際綁定到它自己。
首先,你需要代理對象,這是在這裏解釋: http://tomlev2.wordpress.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
很容易實現。一旦完成,網格中的BindingProxy資源就可以工作,並且可以充當返回到由DataTemplate綁定的項目的錨點。鏈接的文章解釋了原因。
然後,您需要一個轉換器,將兩個對象相互比較。
public class ComparisonConverter : DependencyObject, IValueConverter
{
public object CompareTo
{
get { return (object)GetValue(CompareToProperty); }
set { SetValue(CompareToProperty, value); }
}
public static readonly DependencyProperty CompareToProperty =
DependencyProperty.Register("CompareTo", typeof(object), typeof(ComparisonConverter), new UIPropertyMetadata(null));
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (CompareTo != null)
{
return CompareTo.Equals(value);
}
else
{
return false;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
因此,現在綁定將從菜單的DataContext中選取項目,並將其與ToggleButton所綁定的任何項目進行比較。如果兩個對象匹配,則會顯示單擊/選擇按鈕。如果它們不匹配,則該按鈕看起來不被選中。
所以我碰巧在同一個命名空間中有BindingProxy和我的轉換器。你不一定非得這樣做。我通常有一個名爲「Xaml Trick」的類,我必須編程。
這是很多消化,我很樂意澄清任何事情。
另外一件事......如果你不喜歡「ToggleButton」的外觀,你總是可以讓它們看上去完全不同。有一個ToggleButton購買你的東西是「IsChecked」屬性和Command屬性。您可以使ContentTemplate看起來像您想要的任何東西,這使您在菜單樣式中有很大的自由度。
如果你在你的contextfile屬性(如代碼隱藏文件或視圖模型)表示currentSelectedItem那麼你可以寫在你的XAML如下:
<ListView x:Name="MyList"
ItemsSource="MySource"
SelectedItem="{Binding Path=MyCurrentSelectedItem}" IsSynchronizedWithCurrentItem="True">
代碼隱藏/視圖模型
public MyType MyCurrentSelectedItem { get; set; }
我想你錯過了我的問題。我指的是wpf中的menuitems。不是列表框。我知道與列表框的功能。但是我想知道如果我能用menuitem集合做類似的事情。 –