我对MVVM架构设计很陌生......
我最近一直在努力寻找一个已经为此目的编写的合适的控件,但没有运气,所以我从另一个类似的控件中重用了部分XAML并自己制作了.
我想要实现的是:
有一个可重用的View(usercontrol)+ viewmodel(要绑定到),以便能够在其他视图中使用作为模式覆盖,显示禁用视图其余部分的对话框,并在其上显示一个对话框.

我是如何实现它的:
pseudoXAML:
<usercontrol /customerview/ ...>
<grid>
<grid x:Name="content">
<various form content />
</grid>
<ctrl:Dialog DataContext="{Binding DialogModel}" Message="{Binding Message}" Commands="{Binding Commands}" IsShown="{Binding IsShown}" BlockedUI="{Binding ElementName=content}" />
</grid>
</usercontrol>
Run Code Online (Sandbox Code Playgroud)
因此,模态对话框从Customer视图模型的DialogModel属性获取datacontext,并绑定命令和消息.它也会绑定到对话框显示(绑定到IsShown)时需要禁用的其他元素(此处为'content').当您单击对话框中的某个按钮时,将调用关联的命令,该命令只调用在viewmodel的构造函数中传递的关联操作.
这样我就可以从Customer视图模型中调用对话框视图模型上的对话框的Show()和Hide(),并根据需要更改对话框视图模型.
它会一次只给我一个对话但是没问题.我还认为对话框视图模型将保持单一性,因为单元测试将涵盖在构造函数中使用Actions创建后应该创建的命令的调用.对话框视图会有几行代码隐藏,但很少而且非常愚蠢(setter getters,几乎没有代码).
我关心的是:
这个可以吗?我有什么问题可以进入吗?这会破坏一些MVVM原则吗?
非常感谢!
编辑:我发布了我的完整解决方案,以便您可以更好地了解.欢迎任何建筑评论.如果您看到一些可以纠正的语法,则帖子会被标记为社区维基.
我需要在N个位置向右和向左移动一个数组.
在我转移到的一侧弹出的物品必须回到另一侧.
向右移动13:
[0,1,2,3,4,5,6,7,8,9] -> [7,8,9,0,1,2,3,4,5,6]
Run Code Online (Sandbox Code Playgroud)
向左移15:
[0,1,2,3,4,5,6,7,8,9] -> [5,6,7,8,9,0,1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
此操作将发生数百万次,并且必须非常快.
我目前的实施如下.请查看并建议是否有一些优化要做.
if (shift > 0)
{
int offset = array.Length % shift;
if (offset > 0)
{
byte[] temp = new byte[offset];
if (!right)
{
Array.Copy(array, temp, offset);
Array.Copy(array, offset, array, 0, array.Length - offset);
Array.Copy(temp, 0, array, array.Length - offset, temp.Length);
}
else
{
Array.Copy(array, array.Length - offset, temp, 0, offset);
Array.Copy(array, 0, array, offset, array.Length - offset);
Array.Copy(temp, 0, array, 0, temp.Length);
}
}
}
Run Code Online (Sandbox Code Playgroud)
作为一个关于它将被转移多少的提示(但我怀疑它可以导致优化):
- …Run Code Online (Sandbox Code Playgroud) 我想知道为位图分配的内存的分配和处理如何在.NET中工作.
当我在一个函数的循环中做很多位图创建并连续调用它时,它会一直工作,直到某个时候Bitmap不能分配内存,给出指定大小的异常"Invalid parameter".
如果我在它工作的同时调用垃圾收集器.
使用以下代码,您可以重新生成错误:
class BitmapObject {
public bool Visible {
get { return enb; }
set { enb = value; }
}
private bool enb;
private Bitmap bmp;
public BitmapObject(int i, bool en)
{
enb = en;
bmp = new Bitmap(i, i);
}
}
class Pool<T> where T : BitmapObject
{
List<T> preallocatedBitmaps = new List<T>();
public void Fill() {
Random r = new Random();
for (int i = 0; i < 500; i++) {
BitmapObject item = …Run Code Online (Sandbox Code Playgroud) 在下面的方法中,我发送一个动作的枚举,并希望一个ICommands数组返回该调用Action<object>包装那些动作(relayCommand所需).
问题是,如果我在for each(或者甚至是for循环)中执行此操作,我会得到始终执行参数中传递的第一个操作的命令.
public static ICommand[] CreateCommands(IEnumerable<Action> actions)
{
List<ICommand> commands = new List<ICommand>();
Action[] actionArray = actions.ToArray();
// works
//commands.Add(new RelayCommand(o => { actionArray[0](); })); // (_execute = {Method = {Void <CreateCommands>b__0(System.Object)}})
//commands.Add(new RelayCommand(o => { actionArray[1](); })); // (_execute = {Method = {Void <CreateCommands>b__1(System.Object)}})
foreach (var action in actionArray)
{
// always add the same _execute member for each RelayCommand (_execute = {Method = {Void <CreateCommands>b__0(System.Object)}})
commands.Add(new RelayCommand(o => { action(); }));
}
return commands.ToArray();
} …Run Code Online (Sandbox Code Playgroud) 我在WPF应用程序中使用AvalonDock,需要保持用户设置的AvalonDock的布局(移动,对接,拆分面板).
执行此操作的功能在控件本身(SaveLayout,RestoreLayout).
这样做的正确方法是什么?
现在,我在mainWindowViewModel上有一个命令,它在创建窗口视图和viewmodel的实例时由应用程序创建.它基本上使relay命令调用一个匿名方法,该方法在视图控件上调用所需的函数.这是有效的,因为应用程序为它创建了窗口和视图模型.
但是,如果某个较低级别的视图和视图模型必须这样做,我将如何处理此问题?如果使用这种方法,我还必须在应用程序级别创建Command并通过viewModels将其发送到需要绑定的位置?在它内部,我必须搜索usercontrol,这是一个视图,然后在其中的avalonDock控件,并在应用程序级别使用它,这是容易出错的.不知何故,它似乎很脏......
谢谢!
我有一个使用NAudio的音频播放器,我想为每个频段显示实时强度.
我为每个1024个样本块触发了一个事件:
public void Update(Complex[] fftResults)
{
// ??
}
Run Code Online (Sandbox Code Playgroud)
我想要的是一组数字,表示每个频段的强度.让我们说我想将窗口划分为16个波段.
例如,当有更多低音频率时,它可能如下所示:
????????????????
????????????????
????????????????
????????????????
????????????????
????????????????
Run Code Online (Sandbox Code Playgroud)
如果可以使用该数据,我应该将什么放入该事件处理程序?
来自(Complex [])的数据已经通过FFT进行了转换.这是一个立体声流.
第一次尝试:
double[] bandIntensity = new double[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public void Update(Complex[] fftResults)
{
// using half fftResults because the others are just mirrored
int band = 0;
for (int n = 0; n < fftResults.Length/2; n++)
{
band = (int)((double)n / (fftResults.Length / …Run Code Online (Sandbox Code Playgroud) 我有一个基类,它有一个由派生类执行的方法.该方法由派生类的构造函数以及其中的某些方法或属性引发.我需要确定它是来自该派生类的实例构造函数内部还是之后(在运行时).
以下示例说明了我需要的内容:
public class Base
{
public Base()
{
}
protected void OnSomeAction(object sender)
{
// if from derived constructor EXIT, else CONTINUE
}
}
public class Derived : Base
{
public void Raise()
{
base.OnSomeAction(this); // YES if not called by constructor
}
public Derived()
{
base.OnSomeAction(this); // NO
Raise(); // NO
}
}
class Program
{
static void Main(string[] args)
{
var c = new Derived(); // NO (twice)
c.Raise(); // YES
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我无法更改签名或参数,因为我无法更改派生类.基本上我的想法是确定派生类(发送者)是否完全构造.
所以实现就是这样.我不能在打破派生类的基类中进行更改.我只能对基类进行更改:/
这有可能以某种方式,好还是不好?不幸的是,即使是一些反思魔法或类似的hacky方法也是受欢迎的,因为这是必须的:/.
谢谢!
我有一个CanContentScroll为true的列表框,但其他的都是false.
我正在编写一个需要从中提取滚动查看器并在设备无关像素中计算垂直滚动偏移的行为.
由于CanContentScroll可以是true或false,因此我有时会获得逻辑项单位,而其他时候会获得物理像素.
所以我需要在CanContentScroll为真的情况下计算像素值.
例如:当列表框滚动三个项目时,VerticalOffset将给出3.如何将此3转换为项目使用的垂直像素(大小可能不同)?
谢谢
我有彩色动画的问题.这是我的来源:
<Window.Resources>
<hedit:BrushToColorConverter x:Key="BrushToColorConverter" />
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ControlTemplate.Resources>
<Storyboard x:Key="buttonAnimIn">
<!-- Problem line -->
<ColorAnimation Storyboard.TargetName="bntBack" Storyboard.TargetProperty="Color" To="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource BrushToColorConverter}}" />
</Storyboard>
<Storyboard x:Key="buttonAnimOut">
<ColorAnimation Storyboard.TargetName="bntBack" Storyboard.TargetProperty="Color" To="Blue" />
</Storyboard>
<Storyboard x:Key="buttonAnimForegroundIn">
<ColorAnimation Storyboard.TargetName="btnFore" Storyboard.TargetProperty="Color" To="Blue" />
</Storyboard>
<Storyboard x:Key="buttonAnimForegroundOut">
<ColorAnimation Storyboard.TargetName="btnFore" Storyboard.TargetProperty="Color" To="Red" />
</Storyboard>
</ControlTemplate.Resources>
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3">
<Border.Background>
<SolidColorBrush Color="Blue" x:Name="bntBack" />
</Border.Background>
<ContentControl HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"> …Run Code Online (Sandbox Code Playgroud) 我一直在做一些不安全的位图操作,并发现增加指针的次数可以带来一些重大的性能提升.我不知道为什么会这样,即使你在循环do很多位运算,它仍然是更好地做到上的指针反复次数比较少.
因此,例如,使用UInt64迭代超过32位像素,而不是使用UInt64迭代两个像素,并在一个周期内执行两次操作.
以下是通过读取两个像素并对其进行修改(当然,它会因奇数宽度的图像而失败,但仅用于测试).
private void removeBlueWithTwoPixelIteration()
{
// think of a big image with data
Bitmap bmp = new Bitmap(15000, 15000, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
TimeSpan startTime, endTime;
unsafe {
UInt64 doublePixel;
UInt32 pixel1;
UInt32 pixel2;
const int readSize = sizeof(UInt64);
const UInt64 rightHalf = UInt32.MaxValue;
PerformanceCounter pf = new PerformanceCounter("System", "System Up Time"); pf.NextValue();
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
byte* image = (byte*)bd.Scan0.ToPointer();
startTime = TimeSpan.FromSeconds(pf.NextValue());
for (byte* line = image; line < image + bd.Stride * …Run Code Online (Sandbox Code Playgroud) 我已经为多用户游戏清理和缩短了我的代码片段,以显示我想要完成的任务.所以这里是:
public class Subject {
public List<IObject> Objects = new List<IObject>();
}
public interface IOpenable
{
void Open(Subject by, params string[] p);
void Close(Subject by, params string[] p);
bool IsOpen { get; }
}
public interface IObject {
void Pickup(Subject by, params string[] p);
void Drop(Subject by, params string[] p);
}
public class Box : IObject, IOpenable
{
bool opened = false;
Subject owner = null;
public void Pickup(Subject subject, params string[] p) {
subject.Objects.Add(this);
this.owner = subject;
}
public …Run Code Online (Sandbox Code Playgroud) 有没有办法编写Linq语句来查找B列中的重复,并且只有在A列具有重复值时才能找到它,然后将列B的值添加到找到重复的列.任何帮助表示赞赏谢谢.
RecordID CartID Quantity ProductID
1 11 3 3
2 12 5 6
3 11 6 3
Run Code Online (Sandbox Code Playgroud)
删除记录3并将6添加到RecordID 1的数量,使其变为:
RecordID CartID Quantity ProductID
1 11 9 3
2 12 5 6
Run Code Online (Sandbox Code Playgroud) c# ×12
.net ×6
wpf ×4
algorithm ×2
mvvm ×2
wpf-controls ×2
animation ×1
architecture ×1
asp.net ×1
bitmap ×1
fft ×1
lambda ×1
linq ×1
loops ×1
memory ×1
naudio ×1
optimization ×1
reflection ×1
xaml ×1