我正在尝试使用最近的上传系统,因此我在contextMenu中列出了最近5次(或更少)上传。
问题是我在做静态测试版本(不是动态的)时一切都很好。就像可以显示这个截图:
现在使用我的动态版本:
<ItemsControl ItemsSource="{Binding Uploads}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<MenuItem IsCheckable="False" ItemsSource="{Binding}">
<MenuItem.Icon>
<Image Source="Resources/upload.ico"></Image>
</MenuItem.Icon>
<MenuItem.Header>
<TextBlock Text="{Binding name}"></TextBlock>
</MenuItem.Header>
<DataTemplate>
<StackPanel>
<MenuItem Command="{Binding GoToUrl}" CommandParameter="{Binding url}">
<MenuItem.Header>
<Image IsEnabled="False" HorizontalAlignment="Center" Source="{Binding miniature}"></Image>
</MenuItem.Header>
</MenuItem>
<Separator/>
<MenuItem IsEnabled="False" IsCheckable="False">
<MenuItem.Header>
<StackPanel IsEnabled="False">
<TextBlock IsEnabled="False" Text="{Binding uploadDateText}"></TextBlock>
<TextBlock IsEnabled="False" Text="{Binding viewNumberText}"></TextBlock>
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator/>
<MenuItem Header="Copy To Clipboard" Command="{Binding CopyToClip}" CommandParameter="{Binding url}" />
<MenuItem Header="Open in browser" Command="{Binding GoToUrl}" CommandParameter="{Binding url}" />
<MenuItem Header="Delete" Command="{Binding Delete}" CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</MenuItem>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
问题是当你在另一个menuItem中有一个menuItem时,有一个小箭头,但由于我已经用ItemsControl包装了所有,我无法访问submenuItem,我有一个奇怪的选择错误。
我在this question中看到了有关它为什么没有按预期工作的信息。由于itemsControl就像一个menuItem。但我没有办法以另一种方式做到这一点。
我的目标是MenuItem的“foreach循环”,其中包含其他menuItem。也许我没有一个好的方法。
P.S:对不起我的英语不好,我是法国人。编辑1:
看来我不够清楚,所以我添加了更多信息。
目标:最多有5个菜单foreach上传客户端已完成。如果他只做了3,那么3 Menu将出现在上下文菜单中。 Foreach菜单标题将是他上传的文件的名称。 如果用户想要获得有关上传的更多信息,他将鼠标悬停在上传名称上,然后将绘制子菜单。 此子菜单将显示有关上传的所有信息:图像,大小,上传日期等...
我是怎么做的:我创建了一个类,它将从Web API接收所需的所有信息:上传
public class Upload
{
public string uniqueId { get; set; }
public DateTime uploadedDateTime { get; set; }
public int _viewNumber { get; set; }
public string url { get; set; }
public string minUrl { get; set; }
public string type { get; set; }
public int size { get; set; }
public string name { get; set; }
public BitmapImage miniature
{
get
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(this.minUrl, UriKind.Absolute);
bitmap.EndInit();
return bitmap;
}
}
public string uploadDateText
{
get
{
return "Uploaded : " + this.uploadedDateTime.Date.ToString() + " at " + this.uploadedDateTime.TimeOfDay.ToString();
}
}
public string viewNumberText
{
get
{
return "Number of views : " + this._viewNumber;
}
}
public Upload(string p_uniqueId, DateTime p_uploadedDateTime, int p_viewNumber, string p_url, string p_minUrl, string p_type, int p_size, string p_name)
{
uniqueId = p_uniqueId;
uploadedDateTime = p_uploadedDateTime;
_viewNumber = p_viewNumber;
url = p_url;
minUrl = p_minUrl;
type = p_type;
size = p_size;
name = p_name;
}
public void delete()
{
MessageBox.Show("Deleting item with id : " + this.uniqueId);
}
public void refresh()
{
}
}
因此,当我向我的WebApp询问我的用户的最后5次上传时,我将有一个列表。
最多包含5个项目
要使此列表可用于我的contextMenu,我使用以下代码将其转换为ObservableCollection:
public ObservableCollection<Upload> Uploads
{
get
{
App.GetAppRef().initUploads();
return App.GetAppRef().Uploads;
}
}
我花了很多时间在我的上下文菜单中找到一个可变数量的menuItem的方法。实际上,如果用户只上传了2个文件,则可以有2个menuItem。它是FIFO队列样式(先进先出),最多5个元素。
所以我看一下xaml中的“foreach”等价物。但是我只找到了一种方法来使用ItemsControl进行“xaml foreach”,并将itemSource绑定到我的ObservableCollection上传。
如果有人有更好的想法,请告诉我,因为我知道这可能不是最好的解决方案。
无论如何,我在上下文菜单中的“last 5 upload”部分之前和之后都有其他menuItem,所以我必须在上下文菜单的特定区域内执行foreach。
问题是什么:现在,我无法继续使用我的subitemMenu,并且我已经为我的itemControls启用了选项,所以我需要找到一种更好的方法来实现这一点。
我希望我已经澄清了我的问题。
答案 0 :(得分:0)
好的,花了我一些时间来讨论它,但这里有一个有效的答案(我将它与stackoverflow上的几个答案相结合)。
Xaml:
<local:MyStyleSelector x:Key="MyStyleSelector" />
<Style x:Key="DynamicItemStyle" TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Path=Title}"/>
<Setter Property="ItemsSource">
<Setter.Value>
<x:Array Type="FrameworkElement">
<MenuItem Header="Active" IsCheckable="True" IsChecked="{Binding Path=Active}"></MenuItem>
<Separator></Separator>
<MenuItem Header="Edit" Name="EditCustomMessageButton" Style="{x:Null}"></MenuItem>
<MenuItem Header="Delete" Name="DeleteCustomMessageButton" Style="{x:Null}"></MenuItem>
</x:Array>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="StaticItemStyle" TargetType="MenuItem">
</Style>
在代码中:
public class MyStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
if (item is MyObject)
return (Style)itemsControl.FindResource("DynamicItemStyle");
else
return (Style)itemsControl.FindResource("StaticItemStyle");
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyObject dynamicObject = new MyObject();
dynamicObject.Title = "dynamic1";
Windows.Add(dynamicObject);
Windows.Add(new MyObject() { Title = "dynamic2" });
}
private ObservableCollection<MyObject> _windows = new ObservableCollection<MyObject>();
public ObservableCollection<MyObject> Windows
{
get { return _windows; }
set { _windows = value; }
}
}
public class MyObject
{
public string Title { get; set; }
}
`