我正在尝试将自制控件的属性从我的视图绑定到我的viewmodel。当我将颜色直接绑定到xaml中的另一个元素时,它可以工作,但是当我尝试将它绑定到我的viewmodel中的属性时。财产没有变化。
XAML:
<StackPanel>
<Border Height="50"
BorderBrush="Black"
BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="{Binding color}" />
</Border.Background>
</Border>
<Border Height="50"
BorderBrush="Black"
BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="{Binding ElementName=colorCircle, Path=selectedColor}" />
</Border.Background>
</Border>
<local:ColorCircle x:Name="colorCircle" selectedColor="{Binding color, Mode=OneWayToSource}" />
</StackPanel>
的.cs:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Color _color;
public Color color
{
get { return _color; }
set
{
_color = value;
RaisePropertyChanged("color");
}
}
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
ColorWheel
XAML:
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Transparent">
<Image x:Name="ColorImage"
Width="300"
Height="300"
HorizontalAlignment="Center"
VerticalAlignment="Top"
RenderOptions.BitmapScalingMode="HighQuality"
Source="color_wheel.png" />
<Canvas x:Name="CanvImage"
Width="300"
Height="300"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Background="Transparent">
<Ellipse Width="300"
Height="300"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Fill="Transparent"
MouseDown="Ellipse_MouseDown"
MouseMove="Ellipse_MouseMove"
MouseUp="Ellipse_MouseUp" />
<Ellipse x:Name="ellipsePixel"
Canvas.Left="150"
Canvas.Top="150"
Width="10"
Height="10"
Fill="Transparent"
MouseDown="Ellipse_MouseDown"
MouseMove="Ellipse_MouseMove"
MouseUp="Ellipse_MouseUp"
Stroke="Black"
StrokeThickness="2" />
</Canvas>
</Grid>
的.cs:
public partial class ColorCircle : UserControl
{
public static readonly DependencyProperty SelectedColorProperty =
DependencyProperty.Register("selectedColor", typeof(SolidColorBrush), typeof(ColorCircle));
private SolidColorBrush _selectedColor = new SolidColorBrush(Colors.Transparent);
public SolidColorBrush selectedColor
{
get { return (SolidColorBrush)GetValue(SelectedColorProperty); }
set
{
if (_selectedColor != value)
{
SetValue(SelectedColorProperty, value);
}
}
}
private bool __isMouseDown { get; set; } = false;
private bool _isMouseDown
{
get { return __isMouseDown; }
set
{
__isMouseDown = value;
if (__isMouseDown) ColorSelect();
}
}
public ColorCircle()
{
InitializeComponent();
DataContext = this;
}
private void ColorSelect()
{
try
{
CroppedBitmap cb = new CroppedBitmap(ColorImage.Source as BitmapSource,
new Int32Rect((int)Mouse.GetPosition(CanvImage).X,
(int)Mouse.GetPosition(CanvImage).Y, 1, 1));
byte[] pixels = new byte[4];
try
{
cb.CopyPixels(pixels, 4, 0);
}
catch (Exception) { }
ellipsePixel.SetValue(Canvas.LeftProperty, Mouse.GetPosition(CanvImage).X - 5);
ellipsePixel.SetValue(Canvas.TopProperty, Mouse.GetPosition(CanvImage).Y - 5);
CanvImage.InvalidateVisual();
selectedColor = new SolidColorBrush(Color.FromArgb(255, pixels[2], pixels[1], pixels[0]));
}
catch (Exception) { }
}
private void Ellipse_MouseMove(object sender, MouseEventArgs e)
{
if (_isMouseDown) ColorSelect();
}
private void Ellipse_MouseDown(object sender, MouseButtonEventArgs e)
{
_isMouseDown = true;
}
private void Ellipse_MouseUp(object sender, MouseButtonEventArgs e)
{
_isMouseDown = false;
}
}
colorcircle
有DependencyProperty
selectedColor
,返回Color
。这样可行。我得到第二个边框的颜色但不是第一个...
答案 0 :(得分:2)
你能提供一个不起作用的小例子吗?
我的测试(使用ViewModel的ReactiveUI)工作正常。
的Xaml:
<StackPanel>
<Grid Height="50">
<Grid.Background>
<SolidColorBrush Color="{Binding Color}" />
</Grid.Background>
</Grid>
<ComboBox SelectedItem="{Binding Color, Mode=OneWayToSource}" SelectedIndex="0">
<Color>Red</Color>
<Color>Blue</Color>
<Color>Yellow</Color>
</ComboBox>
</StackPanel>
视图模型:
public class MainViewModel : ReactiveObject
{
private System.Windows.Media.Color _color;
public System.Windows.Media.Color Color
{
get { return _color; }
set { this.RaiseAndSetIfChanged(ref _color, value); }
}
}
答案 1 :(得分:2)
您的代码无法正常工作的原因是您将SolidColorBrush的Color属性绑定到ColorPicker ViewModel中的SolidColorBrush属性
将SelectedColor类型更改为Color
Main Xaml
<StackPanel>
<Border Height="50"
BorderBrush="Black"
BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="{Binding color}" />
</Border.Background>
</Border>
<Border Height="50"
BorderBrush="Black"
BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="{Binding ElementName=colorPicker, Path=SelectedColor}" />
</Border.Background>
</Border>
<local:ColorPicker x:Name="colorPicker" />
</StackPanel>
Xaml.CS For Above XAML
public partial class MainWindow : Window
{
private Color _MyColor;
public Color MyColor
{
get { return _MyColor; }
set { _MyColor = value; }
}
public MainWindow()
{
InitializeComponent();
MyColor = Colors.Orange;
this.DataContext = this;
}
}
ColorPicker.xaml
<Grid>
<Button Click="Button_Click" Content="Click Me To Change Color"/>
</Grid>
ColorPicker.xaml.cs
public partial class ColorPicker : UserControl, INotifyPropertyChanged
{
List<Color> _myColors = new List<Color>()
{ Colors.Yellow, Colors.Green, Colors.Orange, Colors.Red };
public Color SelectedColor
{
get { return (Color)GetValue(SelectedColorProperty); }
set { SetValue(SelectedColorProperty, value); OnPropertyChanged("SelectedColor"); }
}
public static readonly DependencyProperty SelectedColorProperty =
DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorPicker), new PropertyMetadata(null));
public ColorPicker()
{
InitializeComponent();
SelectedColor = _myColors[0];
}
private void Button_Click(object sender, RoutedEventArgs e)
{
int index = _myColors.IndexOf(SelectedColor);
if (index == _myColors.Count - 1)
{
index = 0;
}
else
{
index++;
}
SelectedColor = _myColors[index];
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(String propname)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propname));
}
}
}
答案 2 :(得分:1)
我找到了失败的原因。我需要将ColorCircle的'Datacontext'设置为'this'的'DataContext'。
<local:ColorCircle x:Name="colorCircle"
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
DataContext="{Binding .}"
selectedColor="{Binding selectedColorXaml,
Mode=TwoWay}" />
所以'DataContext =“{Binding。}”'是anwser ......
答案 3 :(得分:0)
您应该使用System.Windows.Media.Brush
代替System.Windows.Media.Color
来更改Control
的颜色。也就是说,您的财产应该是:
private System.Windows.Media.Brush _selectedColor
public System.Windows.Media.Brush selectedColorXaml
{
get { return _selectedColor; }
set
{
_selectedColor = value;
RaisePropertyChanged("selectedColorXaml");
}
}
就像一个小建议一样,用大写字母命名你的财产。像那样:
private System.Windows.Media.Brush _selectedColor { get; set; }
public System.Windows.Media.Brush SelectedColorXaml
{
get { return _selectedColor; }
set
{
_selectedColor = value;
RaisePropertyChanged("SelectedColorXaml");
}
}
我为你做了一个测试,它确实有效:
<强>视图模型:强>
public YourViewModel
{
Timer timer;
public YourViewModel()
{
timer = new Timer(1000);
timer.Elapsed += Timer_Elapsed;
timer.Enabled = true;
}
int count = 0;
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(count%2==0)
FooColor = Brushes.Green;
else
FooColor = Brushes.Red;
count++;
}
private Brush fooColor;
public Brush FooColor
{
get { return fooColor; }
set
{
fooColor = value;
OnPropertyChanged("FooColor");
}
}
}
XAML:
<Window
xmlns:vm="clr-namespace:TreeViewMVVM.ViewModel">
<Window.DataContext>
<vm:YourViewModel/>
</Window.DataContext>
<Grid>
<Button Content="Click me!" Background="{Binding FooColor}"/>
<Grid>
</Window>
更新2:
我的问题是,我无法将所选颜色从视图中恢复到我的viewMode
首先,您应该在视图模型中为SelectedItem创建属性:
private Color selectedItem=new object();
public Color SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;//here is you Selected Color
}
}
并在XAML中:
<ComboBox x:Name="colorBox"
SelectedIndex="0"
SelectedItem="{Binding SelectedItem}">
<Color>Red</Color>
<Color>Blue</Color>
<Color>Yellow</Color>
</ComboBox>