WPF =>将ContextMenu与CollectionViewSource绑定

时间:2017-03-07 13:31:40

标签: c# wpf xaml binding

为什么这样做:

<Button x:Name="btnCritereAdd" Content="{Binding Source={x:Static resx:resMain.lblCriterAdd}}" Style="{StaticResource btnStandardClr}" Click="btnMenuPopup_Click" ContextMenuService.Placement="Bottom">
    <Button.ContextMenu>
        <ContextMenu x:Name="cmuCriteres">
            <ContextMenu.ItemsSource>
                <Binding Path="CriteresDispo" />
            </ContextMenu.ItemsSource>
            <ContextMenu.InputBindings>
                <MouseBinding MouseAction="LeftClick" Command="" />
            </ContextMenu.InputBindings>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

但不是这样:

<Button x:Name="btnCritereAdd" Content="{Binding Source={x:Static resx:resMain.lblCriterAdd}}" Style="{StaticResource btnStandardClr}" Click="btnMenuPopup_Click" ContextMenuService.Placement="Bottom">
    <Button.ContextMenu>
        <ContextMenu x:Name="cmuCriteres">
            <ContextMenu.Resources>
                <CollectionViewSource x:Key="cvsCriteres" Source="{Binding CriteresDispo}"/>
            </ContextMenu.Resources>
            <ContextMenu.ItemsSource>
                <Binding Source="{StaticResource cvsCriteres}" />
            </ContextMenu.ItemsSource>
            <ContextMenu.InputBindings>
                <MouseBinding MouseAction="LeftClick" Command="" />
            </ContextMenu.InputBindings>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

我在CodeBehind中的Button上设置DataContext:

btnCritereAdd.DataContext = vmFiltresChamps;

我试过&#34; UpdateSourceTrigger = PropertyChanged&#34;和#34; NotifyOnSourceUpdated = True&#34;关于这两个案子但没有任何改变。 清单是空的......

你有什么想法吗?

VM方面: 属性:

public ItemCollection CriteresDispo { get { return _CriteresDispo; } set { _CriteresDispo = value; RaisePropertyChanged(nameof(CriteresDispo)); } }

由代码调用的命令

public RelayCommand<ItemCollection> LoadCriteresCommand { get; set; }

private void LoadCriteres(ItemCollection obj) {
        var ht = new tblFiltreChamps();
        Classes.clsUtils.GetFiltresSel(obj, ht);
        CriteresDispo = new ItemsControl().Items;
        if (ht.items.Count > 0) {
            foreach (var item in ht.items.OrderBy((x) => x.Desc).ToList()) {
                var mi = new MenuItem() { Header = item.Desc, Tag = item };
                mi.Command = AddCritereCommand;
                mi.CommandParameter = item;
                CriteresDispo.Add(mi);
            }
        }
        if (CriteresAddAction != null) CriteresAddAction();
}

2 个答案:

答案 0 :(得分:0)

// Directory crawler // Written by Kaz #include<iostream> #include <dirent.h> #include<string.h> #include <errno.h> #include <stdio.h> #include<string> #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> #include<stdlib.h> using namespace std; int binCount = 0; // count of total bins which are nodes in the linked-list struct node{ int count, name, min, max; node* next, *prev; node(){ name = binCount; count = 0; min = 0; max = 0; prev = NULL; next = NULL; } node(node *other){ if(other == NULL){ } else{ node* objCopy = other; node* temp = this; while(objCopy != NULL){ temp->next = new node; temp->next->name = objCopy->name; temp->next->count = objCopy->count; temp->next->min = objCopy->min; temp->next->max = objCopy->max; temp->next->prev = objCopy->prev; temp = temp->next; objCopy = objCopy->next; } } } }; /* void nextNode(node* previousNode, int binWidth){ node *nextLink = new node; nextLink->count = 1; nextLink->min = previousNode->max + 1; nextLink->max = previousNode->max + binWidth; nextLink->prev = previousNode; previousNode ->next = nextLink; } */ node* traverseNewDirectory(node *here, const char *dirName, int binWidth){ DIR * nwd; struct dirent *dip; node * current = new node(here); // Deep copy? //current = here; bool isadirectory,isHidden; if((nwd = opendir(dirName))== NULL){ perror("Can't open derived directory"); return NULL; } while ((dip = readdir(nwd)) != NULL){ isadirectory = false; isHidden = false; if((dip -> d_type) == DT_UNKNOWN ){ struct stat stbuf; stat(dip->d_name, &stbuf); isadirectory = S_ISDIR(stbuf.st_mode); } else if((dip -> d_type) == DT_DIR ){ if((strcmp(dip->d_name, ".") == 0) || (strcmp(dip->d_name, "..")) == 0){ isHidden = true; isadirectory = true; } else{ isadirectory = true; } } else{ if((dip-> d_reclen <= current->max)&&(dip->d_reclen >=current->min)){ current->count = current->count+1; } else if(dip->d_reclen < current->min){ node*temp = current->prev; while(temp != NULL){ if((dip-> d_reclen <= temp->max)&&(dip->d_reclen >=temp->min)){ temp->count = temp->count+1; break; } else if(dip->d_reclen < temp->min){ temp = temp->prev; } } } else{ current->next = new node; current->next->count = 1; current->next->min = current->max + 1; current->next->max = current->max + binWidth; current->next->prev = current; current = current->next; binCount++; } } if(isadirectory){ string path = string(dirName) + "/"+dip->d_name; /* strcpy(path,dirName); strcat(path, "/"); strcat(path,dip->d_name); strcat(path, "\0"); */ if(isHidden == true){} else{ current->next = new node(traverseNewDirectory(current, path.c_str(), binWidth)); if(current->next != NULL){ current = current->next; binCount++; } } } } while ( ( closedir (nwd) == -1) && ( errno == EINTR) ); if(current == here){ return NULL; } else{ return current; } } void printHistogram(node *head){ node*temp; temp = head; while(temp!=NULL){ cout << "[B " << temp->name << "] from " << temp->min << " to " << temp->max << " : "; for(int i = 0; i < temp->count; i++){ cout << "x"; } cout << endl; temp = temp->next; } } int main(int argc,char *argv[]){ // Ensures that a valid directory is provided by the cmd line argument if (argc != 3){ if(argc == 1){ fprintf (stderr, " argc = %d no directory given \n", argc); return 1; } else if(argc == 2){ fprintf (stderr, " argc = %d no size given \n", argc); return 2; } else{ fprintf(stderr, "argc = %d invalid parameters \n", argc); return 3; } } DIR * cwd; // current working directory pointer struct dirent *cwdP; // pointer to dirent struct int binWidth; // variable for the width of the grouping in the histogram binWidth = atoi(argv[2]); binWidth = binWidth - 1; node *first = new node; first->max = binWidth; binCount++; node * current; current = first; bool isadirectory,isHidden; if((cwd = opendir(argv[1]))== NULL){ perror("Can't open main directory"); return 2; } while ((cwdP = readdir(cwd)) != NULL){ isadirectory = false; isHidden = false; if((cwdP -> d_type) == DT_UNKNOWN ){ struct stat stbuf; stat(cwdP->d_name, &stbuf); isadirectory = S_ISDIR(stbuf.st_mode); } else if((cwdP -> d_type) == DT_DIR ){ if((strcmp(cwdP->d_name, ".") == 0) || (strcmp(cwdP->d_name, "..")) == 0){ isHidden = true; isadirectory = true; } else{ isadirectory = true; } } else{ if((cwdP-> d_reclen <= current->max)&&(cwdP->d_reclen >=current->min)){ current->count = current->count+1; } else if(cwdP->d_reclen < current->min){ node*temp = current->prev; while(temp != NULL){ if((cwdP-> d_reclen <= temp->max)&&(cwdP->d_reclen >=temp->min)){ temp->count = temp->count+1; break; } else if(cwdP->d_reclen < temp->min){ temp = temp->prev; } } } else{ /* nextNode(current,binWidth); current = current ->next; //binCount++; */ current->next = new node; current->next->count = 1; current->next->min = current->max + 1; current->next->max = current->max + binWidth; current->next->prev = current; current = current->next; binCount++; } } if(isadirectory){ string fullPath = string(argv[1]) + "/" + cwdP ->d_name; /* strcpy(path,dirName); strcat(path, "/"); strcat(path,dip->d_name); strcat(path, "\0"); */ if(isHidden == true){} else{ current->next = new node(traverseNewDirectory(current, fullPath.c_str(), binWidth)); if(current->next != NULL){ current = current->next; binCount++; } } } } while ( ( closedir (cwd) == -1) && ( errno == EINTR) ); printHistogram(first); return 0; } 未实现CollectionViewSource,因此无法设置为IEnumerable的{​​{1}}属性,其类型为ItemsSource

因此您需要更改:

ContextMenu

要:

IEnumerable

这会将<ContextMenu.ItemsSource> <Binding Source="{StaticResource cvsCriteres}"/> </ContextMenu.ItemsSource> 设置为<ContextMenu.ItemsSource> <Binding Source="{StaticResource cvsCriteres}" Path="View"/> </ContextMenu.ItemsSource> 的{​​{1}}属性,其类型为ItemsSource 实施CollectionViewSource

答案 1 :(得分:0)

  

你有什么想法吗?

绑定到StaticResource时,如果为绑定到{{1}的PropertyChanged属性的属性引发Source事件,则不会更新目标属性}}。

这就是区别。

您需要绑定到属性,并为CollectonViewSource集合的此特定属性引发PropertyChanged事件以进行刷新。