我有一个自定义的滑块,并试图把它放在一个列表视图与网格,使列表视图显示以下内容:左上:列表中的字符串项。左下:(在每个项目下)自定义滑块。(向右/第二列:每个项目的整数/数字值)。
自定义滑块是用NuGet包SkiaSharp制作的,名为“x:Name=“balloon_slider”"。当我把自定义滑块放在xaml中的列表视图中时-它不再能在C#中引用(在当前上下文中不存在)。(它在列表视图之外工作。)下面是列表视图的xaml代码:
<ListView x:Name="displaylist100" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!--Items from list as strings-->
<Grid Grid.Column="0">
<Label x:Name="listlabel"
Text="{Binding Text}"
HorizontalTextAlignment="Center"
FontSize="Medium"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
Padding="10, 10"
Margin="0,5,5,0"/>
<!--SkiaSharp Balloon_slider-->
<Grid>
<skia:SKCanvasView x:Name="balloon_slider"
PaintSurface="Handle_Slider_PaintSurface"/>
<local:BalloonView x:Name="balloonSvg"/>
<Grid.Effects>
<local:TouchEffect
TouchAction="Handle_TouchAction"/>
</Grid.Effects>
</Grid>
<!--Value displayed to the right-->
<Label Text="{Binding DisplayValue, Mode=TwoWay}"
FontSize="Medium"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Padding="10, 10"
Grid.Column="1"/>
</Grid>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我使用的滑块是这个的定制版本:“https://github.com/memsranga/Balloony网站“。
我试着用这个:“var balloon_slider =(SKCanvasView)listView.FindByName(“气球滑块”);在“InitializeComponent()”中;“部分-但它似乎并没有使它连接两者。我也试图在列表视图中有一个标准的滑块-这是可行的。所以我的问题是:我怎么能引用滑块从我的C#背后时,它是在列表视图?
更新:这是气球滑块项目的代码-我有点困惑,我需要改变什么才能进行绑定。目前,每个“balloon_slider”和“balloonSvg”都有错误,即找不到:
using System;
using System.Diagnostics;
using System.Xml.Linq;
using SkiaSharp;
using SkiaSharp.Views.Forms;
using Xamarin.Forms;
using static Balloony.TouchEffect;
namespace Balloony
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
SliderSelectedPaint = new SKPaint
{
Color = Color.FromHex("#eb0000").ToSKColor(),
IsAntialias = true,
Style = SKPaintStyle.Fill,
StrokeWidth = SliderHeight
};
SliderUnSelectedPaint = new SKPaint
{
Color = Color.FromHex("#f8f8f8").ToSKColor(),
IsAntialias = true,
Style = SKPaintStyle.Stroke,
StrokeWidth = SliderHeight
};
ThumbPaint = new SKPaint
{
Color = Color.FromHex("#eb0000").ToSKColor(),
IsAntialias = true,
Style = SKPaintStyle.Fill
};
ThumbSelectedPaint = new SKPaint
{
Color = Color.FromHex("#eb0000").ToSKColor(),
IsAntialias = true,
Style = SKPaintStyle.Stroke,
StrokeWidth = SelectedThumbThickness
};
ThumbSelectedSubtractPaint = new SKPaint
{
Color = Color.Transparent.ToSKColor(),
IsAntialias = true,
Style = SKPaintStyle.Fill,
StrokeWidth = 0,
BlendMode = SKBlendMode.Src
};
ThumbSubtractPaint = new SKPaint
{
Color = Color.Transparent.ToSKColor(),
IsAntialias = true,
Style = SKPaintStyle.Fill,
StrokeWidth = 0,
BlendMode = SKBlendMode.Src
};
Percent = 50;
}
float SliderHeight = 5;
float SelectedThumbThickness = 10;
float ThumbSize = 50;
SKPaint SliderSelectedPaint { get; set; }
SKPaint SliderUnSelectedPaint { get; set; }
SKPaint ThumbPaint { get; set; }
SKPaint ThumbSubtractPaint { get; set; }
SKPaint ThumbSelectedPaint { get; set; }
SKPaint ThumbSelectedSubtractPaint { get; set; }
private TouchActionType _touchType;
private double _width;
private float _percent;
public float Percent
{
get => _percent;
private set
{
_percent = value;
balloon_slider.InvalidateSurface();
TranslateBalloon(Percent);
}
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
// only calling when orientation changes
if (Math.Abs(width - _width) > 0.01)
{
_width = width;
balloonSvg.AnchorY = 1;
balloonSvg.TranslationX = (balloon_slider.Width * Percent / 100) - balloonSvg.Width / 2;
balloonSvg.Scale = 0;
balloonSvg.TranslationY = balloon_slider.Height;
}
}
void Handle_Slider_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
{
var info = e.Info;
var canvas = e.Surface.Canvas;
canvas.Clear();
DrawSlider(canvas, info, Percent);
DrawThumb(canvas, info, Percent, _touchType);
}
private void TranslateBalloon(float percent)
{
if (this.AnimationIsRunning("TranslationAnimation"))
{
return;
}
var oldX = balloonSvg.TranslationX;
var newX = balloon_slider.Width * percent / 100 - balloonSvg.Width / 2;
balloonSvg.Text = Math.Floor(Percent).ToString();
var translation = new Animation();
translation.Add(0, 1, new Animation((s) =>
{
if (oldX > newX)
{
var delta = oldX - s * Math.Abs(oldX - newX);
balloonSvg.TranslationX = delta;
}
else
{
var delta = oldX + s * Math.Abs(oldX - newX);
balloonSvg.TranslationX = delta;
}
}, 0, 1));
translation.Add(0, 1, new Animation(s =>
{
if (oldX > newX)
{
var delta = oldX - s * Math.Abs(oldX - newX);
var angle = Math.Abs(oldX - newX) > 0.001 ? Math.Tanh((oldX - newX) / balloon_slider.Width) : 0;
balloonSvg.Rotation = angle * 180;
}
else
{
var delta = oldX + s * Math.Abs(oldX - newX);
var angle = Math.Abs(oldX - newX) > 0.001 ? Math.Tanh((oldX - newX) / balloon_slider.Width) : 0;
balloonSvg.Rotation = angle * 180;
}
}, 0, 1, finished: () =>
{
balloonSvg.RelRotateTo(-balloonSvg.Rotation, 500);
}));
translation.Commit(balloonSvg, "TranslationAnimation", length: 100);
}
private void DrawThumb(SKCanvas canvas, SKImageInfo info, float percent, TouchActionType touchActionType)
{
var y = info.Height - ThumbSize - SelectedThumbThickness;
var center = info.Width * percent / 100;
if (touchActionType == TouchActionType.Pressed || touchActionType == TouchActionType.Moved)
{
// selected thumb
var radius = ThumbSize * 0.5f; // 50% of size
canvas.DrawCircle(center, y, radius, ThumbSelectedPaint);
canvas.DrawCircle(center, y, radius, ThumbSelectedSubtractPaint);
return;
}
//default thumb
var startX = center - ThumbSize / 2;
var startY = y - ThumbSize / 2;
var cornerRadius = ThumbSize * 0.4f; // 40% of size
var innerRadius = ThumbSize / 2 * .5f; // 50 % of side
canvas.DrawRoundRect(startX, startY, ThumbSize, ThumbSize, cornerRadius, cornerRadius, ThumbPaint);
canvas.DrawCircle(center, y, innerRadius, ThumbSubtractPaint);
}
private void Handle_TouchAction(object sender, Balloony.TouchEffect.TouchActionEventArgs args)
{
_touchType = args.Type;
if (this.AnimationIsRunning("FloatAnimation") || this.AnimationIsRunning("DropAnimation"))
{
return;
}
if (_touchType == TouchActionType.Pressed || _touchType == TouchActionType.Entered)
{
Debug.WriteLine("entered");
var floatAnimation = new Animation();
floatAnimation.Add(0, 1, new Animation((s) =>
{
balloonSvg.Scale = s;
balloonSvg.TranslationY = (balloon_slider.Height - balloonSvg.Height - 88) - s * -45;
}, 0, 1));
floatAnimation.Commit(balloonSvg, "FloatAnimation");
}
else if (_touchType == TouchActionType.Released || _touchType == TouchActionType.Exited)
{
var dropAnimation = new Animation();
dropAnimation.Add(0, 1, new Animation((s) =>
{
balloonSvg.Scale = s;
balloonSvg.TranslationY = (balloon_slider.Height - balloonSvg.Height - 88) - s * -45;
}, 1, 0));
dropAnimation.Commit(balloonSvg, "DropAnimation");
}
Percent = (float)((args.Location.X / balloon_slider.Width) * 100 - 15);
if (Percent > 100)
{
Percent = 100;
}
if (Percent < 0)
{
Percent = 0;
}
if (Percent < 20)
{
}
}
private void DrawSlider(SKCanvas canvas, SKImageInfo info, float percent)
{
var y = info.Height - ThumbSize - SelectedThumbThickness; // minus the thumb radius, minus thumb thickness
percent = Math.Min(percent, 100);
var selectX = info.Width * percent / 100;
canvas.DrawLine(0, y, selectX, y, SliderSelectedPaint);
canvas.DrawLine(selectX, y, info.Width, y, SliderUnSelectedPaint);
}
}
}
1条答案
按热度按时间9jyewag01#
正如Jason所说,模板化控件中的元素不能被Name引用。
如果你在ListView中的
SKCanvasView
中添加事件,并在YourPage.xaml.cs
中实现这个函数,你可以通过参数sender
获得View的示例。请参考以下代码:
更新日期:
一般来说,我们建议使用
MVVM
和data binding
来实现这一点,为了进行比较,我添加了两个按钮,一个使用Command
方法响应click事件,另一个添加Clicked
事件。您可以参考以下代码:
我的视图模型.cs
项目.cs
主页.xaml
主页.xaml.cs